首页 > 解决方案 > range.getBoundingClientRect() 在选择一个节点并折叠范围后为所有值返回零

问题描述

我有这个标记span,当我选择它并折叠范围时,我想记录范围的当前位置,但调用getBoundingClientRect对所有值都返回零。在选择节点并折叠后,我能做些什么让它返回正确的值?

$('button').on('click', function() {
  const range = document.createRange();
  const $marker = $('#marker');

  range.selectNode($marker.get(0));

  range.collapse();

  const sel = window.getSelection();
  sel.removeAllRanges();
  sel.addRange(range);

  console.log(range.getBoundingClientRect());
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="wrapper" contenteditable="true">
  hello <span id="marker"></span> world
</div>
<button>go to marker</button>

标签: javascripthtmlrangecontenteditable

解决方案


这有效:
我在范围内插入一个“零宽度空间”并再次调用 getBoundingClientRect。
然后删除空格。

function rangeRect(r){
  let rect = r.getBoundingClientRect();
  if (r.collapsed && rect.top===0 && rect.left===0) {
    let tmpNode = document.createTextNode('\ufeff');
    r.insertNode(tmpNode);
    rect = r.getBoundingClientRect();
    tmpNode.remove();
  }
  return rect;
}

$('button').on('click', function() {
  const range = document.createRange();
  const $marker = $('#marker');

  range.selectNode($marker.get(0));

  range.collapse();

  const sel = window.getSelection();
  sel.removeAllRanges();
  sel.addRange(range);

  console.log(rangeRect(range));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="wrapper" contenteditable="true">
  hello <span id="marker"></span> world
</div>
<button>go to marker</button>


推荐阅读