【问题标题】:Get click range relative to parent element获取相对于父元素的点击范围
【发布时间】:2018-02-16 01:06:45
【问题描述】:

所以我遇到了这个问题,我需要获取相对于父元素的点击点偏移量。 让我们假设我的 html 是这样渲染的:

<div>
   able   to   allocate   many   IPs.
   <span style="background: yellow">
      Proof-of-work   is   essentially   one-CPU-one-vote.
   </span>     The   majority
</div>

我想获取点击相对于父 div 的偏移量。例如,如果我单击单词在跨度标签中,我将获得单击相对于父 Div 的偏移量。我该如何实现这一点。 我试过写这样的代码:

var selection = window.getSelection();
var range = selection.getRangeAt(0);
var offset = range.startOffset;

但这给了我相对于 span 标签的偏移量。那么如何获取相对于 div 标签的偏移量呢?

【问题讨论】:

  • 澄清一下...当您说“点击”时,您并不是在谈论实际的click event 而是屏幕坐标(clientXclientY),对吗?您实际上的意思是您想要所选文本相对于文本的父元素或祖父元素的偏移量?
  • 是的,完全正确。我想要所选文本的偏移量。
  • 考虑到最终用户可以单击文档中的任意位置,您如何知道要选择相对于哪个 div 节点?
  • 我希望它获得最接近它的 div。我有一个 pdf 文件,上面呈现了文本层。我在上面注册了 onClick 事件。当 div 中没有 span 标签时,我会进行一系列字符串分析计算并将带有样式的 span 标签添加到文本层。现在,当单击的 dom 元素是跨度标记时,我想获取单击点相对于跨度父节点的偏移量。这是必需的,因为我通过句子结束标记(?!。)索引识别句子。因此,要正确删除跨度标记,我需要在我的上下文 div 中相对于 parentNode 的单击点的偏移量

标签: javascript dom range offset


【解决方案1】:

我不知道有任何内置函数可以测量 Range 相对于另一个元素的偏移量。您可以使用 Range 的 startContainer 属性,然后向上爬过 DOM 层次结构,同时测量内容。

我在下面创建了一个演示。但是请注意,这可能会或可能不会产生您正在寻找的结果。例如,这将测量 cmets 和样式节点的长度,并将计算所有空格字符,无论浏览器最终是否呈现它们。您可能需要通过在测量之前添加对nodeType 的检查、预折叠空格字符(可能使用正则表达式替换)等来进行调整以适应您自己的目的,但我希望这是一个好的起点。

function clicked(){
  console.log( getSelectionOffsetRelativeTo( document.getElementById( 'parent' ) ) );
}

function getSelectionOffsetRelativeTo(parentElement, currentNode){

  var currentSelection, currentRange,
      offset = 0,
      prevSibling,
      nodeContent;
      
  if (!currentNode){
    currentSelection = window.getSelection();
    currentRange = currentSelection.getRangeAt(0);
    currentNode = currentRange.startContainer;
    offset += currentRange.startOffset;
  }
    
  if (currentNode === parentElement){
    return offset;
  }
  
  if (!parentElement.contains(currentNode)){
    return -1;
  }
  
  while ( prevSibling = (prevSibling  || currentNode).previousSibling ){
    nodeContent = prevSibling.innerText || prevSibling.nodeValue || "";
    offset += nodeContent.length;
  }
  
  return offset + getSelectionOffsetRelativeTo( parentElement, currentNode.parentNode );

}
Click inside the div:

<div id="parent" style="border: black 1px solid;" onclick="javascript:clicked();">

  Currently in the parent node.

  <span style="color: red;">In the first child span.</span>

  Back in the parent node.

  <span style="color: red;">In the second child span.

    <span style="font-style:italic;">In the grandchild span.</span>

  </span>

  Back in the parent node.

</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-15
    • 2012-04-12
    • 2011-06-27
    • 2023-03-13
    • 1970-01-01
    • 2014-11-25
    相关资源
    最近更新 更多