0

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

现在有这样的简单样本

<html>
  .
  .
   <p>The quick brown fox jumps over the lazy dog</p>
  .
  .
</html>

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

再说一次,因为我真的只是想测试一下,所以暂时非常简单的 CS。

$(document).ready ->

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

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

例如,如果我将鼠标悬停在 fox 中,我希望偏移量返回为 16,这样我就可以像这样设置范围的开始range.setStart(target,16)

任何帮助我朝着正确的方向前进将不胜感激。

编辑:在输入并提交后,我意识到期望元素给我返回偏移信息是多么愚蠢。我很迷茫,请指导我。

4

2 回答 2

1

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

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
于 2013-08-27T02:20:22.457 回答
0

你应该使用 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/


编辑

如果您需要获取悬停字符的索引,可以使用如下技巧:

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

<span>The quick brown fox jumps over the lazy dog</span>

然后进行以下计算

$(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}")

你可以在这里检查它的工作。我已将事件设置为单击,以便您可以在 fox 的 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 += '<span>' + char + '</span>'

  // 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/

于 2013-08-25T11:24:52.757 回答