javascript - 获取相对于父元素的点击范围

标签 javascript dom range offset

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

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

我想获取click相对于父div的偏移量。例如,如果我单击 span 标签中的单词,我将获得单击相对于父 Div 的偏移量。我怎样才能实现这个。 我尝试编写这样的代码:

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

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

最佳答案

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

我在下面创建了一个演示。但请注意,这可能会也可能不会产生您正在寻找的结果。例如,这将测量注释和样式节点的长度,并将计算所有空格字符,无论浏览器最终是否渲染它们。您可能需要通过添加 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>

关于javascript - 获取相对于父元素的点击范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48810664/

相关文章:

java - 将范围列表缩小为整数数组

javascript - 单向数据流 : alleviating rework when dealing with a huge list of items?

javascript - 计算动态加载的 div 的高度

c# - 如何使用 C# 在 Excel 中获取用户选定范围内的特定单元格

javascript - 哈希表比 document.getElementById 更快吗?

Javascript 从嵌套 Div 中获取 Div 信息

MySQL:如何在某些条件下选择特定时间范围之间的最大/最小时间数据?

javascript - jquery 不改变调用 ajax 页面的输入值

javascript - 如果选中了 2 个特定的复选框,则显示一个 div,如果选中了 1 个复选框,则显示另一个(如果选中了 2 个复选框,则不显示它)

javascript - 尽管由 ajax 加载,但 DOM 元素只是偶尔创建