【问题标题】:Using mouse cursor position as a range starting point in CoffeeScript/JavaScript在 CoffeeScript/JavaScript 中使用鼠标光标位置作为范围起点
【发布时间】:2013-08-28 00:23:36
【问题描述】:

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

现在有这样的简单示例

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

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

再说一次,我现在真的很简单,因为我只是想测试一下。

$(document).ready ->

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

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

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

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

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

【问题讨论】:

    标签: javascript jquery coffeescript range


    【解决方案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
    

    【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 但是如何将 x 和 y 坐标转换为偏移量?
    • SlowBucket 你能告诉我们它是否有帮助或者你还需要帮助吗?
    • 抱歉,只有坐标并不能帮助我创建范围。我不精通 JS,所以如果你知道一种获取坐标并在这里使用它们的方法developer.mozilla.org/en-US/docs/Web/API/Range.setStart,你将是我的英雄。
    • 嘿,我想我终于找到了一个很好的解决方案,请参阅我的 EDIT 2
    • 感谢您的努力!我试图避免跨度技巧,但如果我没有找到我发布的解决方案,我会使用你的。
    猜你喜欢
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 2013-08-02
    相关资源
    最近更新 更多