使用鼠标光标位置作为CoffeeScript / JavaScript中的范围起点

正如标题所述,我想用光标的位置作为范围的起点。

现在有这样的简单样本

 . . 

The quick brown fox jumps over the lazy dog

. .

在CS / JS方面,我将事件监听设置为鼠标移动,试图打印出光标位置的偏移量,但是我没有使用正确的方法,最终得到undefinedno method error

再一次,非常简单的CS,因为我真的只想测试它。

 $(document).ready -> $(document).mousemove -> target = event.target console.log("#{target.offset()}") // also tried .rangeOffset .offset 

理想情况下,我想要一些可以输入到range.setStart()函数中的东西。

例如,如果我要在狐狸中使用m,我会希望偏移量返回为16,这样我就可以设置范围的开始,如range.setStart(target,16)

任何有助于我正确指导的帮助将不胜感激。

编辑:在输入并提交之后,我意识到期望元素给我回复偏移信息是多么愚蠢。 我非常失落,请指导我。

经过大量的谷歌搜索和数小时的故障排除后,我终于想出了一个适合我的目的的解决方案。

函数document.caretPositionFromPoint()或Webkit document.caretRangeFromPoint()从事件中获取X和Y坐标,并返回一个插入位置,然后我可以使用它来创建我的范围的起点。

 $(document).ready -> setRange = (event) -> if document.caretPositionFromPoint #for Firefox else if document.caretRangeFromPoint range = document.caretRangeFromPoint(event.pageX, event.pageY) targetNode = range.startContainer offset = range.startOffset range.setStart(targetNode, offset) range.setEnd(targetNode, 10) #just to test sel = window.getSelection() sel.removeAllRanges() sel.addRange(range) element = document.getElementById("content") element.addEventListener('mousemove', setRange, true) #eventlistener instead of .mousemove for event bubbling 

你应该使用pageX或pageY,就像这样

 $(document).ready -> $(document).mousemove (e) -> console.log("#{e.pageX}") console.log("#{e.pageY}") 

例如,如果你需要获得相对于div的位置

 $(document).ready -> $(document).mousemove (e) -> console.log("#{e.pageX - $('#divID').offset().left}") console.log("#{e.pageY - $('#divID').offset().top}") 

适用于您的情况,它会给你这样的东西

 $(document).ready -> $('p').mousemove (e) -> console.log("#{e.pageX - $('p').offset().left}") console.log("#{e.pageY - $('p').offset().top}") 

将鼠标移动到包含文本的段落上会在段落中显示鼠标位置

看到它在这里工作http://jsfiddle.net/zXnk9/


编辑

如果你需要得到你正在盘旋的角色的索引,你可以使用这样的技巧:

将文本包装在与文本宽度完全相同的容器中

 The quick brown fox jumps over the lazy dog 

然后进行以下计算

 $(document).ready -> // define the container for the text you are intersted in container = $('span') // on mouseover container.mouseover (e) -> // get container width container_width = container.width() // compute the avg character width base on the container width and the number of characters contained in your text. // (If you have some complex formatting inside your container, you would have to adjust this calculation.) char_width = p_width / container.text().length // get the position of your mouse inside position_inside = e.pageX - container.offset().left // define the index of the character you are interested in char_index = Math.floor(position_inside / char_width) - 1 // use it as you wish // print it for example console.log("#{char_index}") 

你可以在这里查看它。 我已将事件设置为单击以便您可以在狐狸的f上精确地尝试它,它返回16. http://jsfiddle.net/zXnk9/1/

编辑2:以可靠的方式做你想做的事

加载文档时,将容器中的每个字符放入一个html节点,就像这样

 $(document).ready -> // set your container container = $('span') // define a replacement text string replacement_container_text = '' // iterate over each character inside your container $(container.text().split('')).each (i, char) -> // put it inside a span and add it to your replacement text string replacement_container_text += '' + char + '' // set the replacement text string as the html content of your container // this replaces the original text with the initial text with each // character wrapped into a span // (which can then be caught as targets for your mousemove events) container.html(replacement_container_text) 

然后,您可以使用以下内容获取鼠标所在的字符的索引

 container.mousemove (e) -> range_start = container.children('span').index $(e.target) console.log(range_start) 

这适用于多行容器,段落等。

查看工作示例http://jsfiddle.net/2TBFV/