Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

range.getBoundingClientRect() returns zero for all values after selecting a node and collapsing the range

I have this marker span and when I select it and collapse the range, I want to log the range's current position, but calling getBoundingClientRect keeps returning zero for all values. Is there anything I can do to make it return the correct values after selecting a node and collapsing?

$('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>
like image 754
Amr Noman Avatar asked Sep 17 '25 14:09

Amr Noman


1 Answers

This works:
I insert a "zero width space" in the range and again call getBoundingClientRect.
Then remove the the space.

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>
like image 91
Tobias Buschor Avatar answered Sep 20 '25 03:09

Tobias Buschor