1

I'm aware that for an element, we can use getBoundingClientRect(). However for a Node, I'm unable to find an equivalent that can give me a top and bottom so that I can overlay something at that area of the page. The use case I have for this is on selection.focusNode.

Clement Hoang
  • 675
  • 9
  • 18

1 Answers1

1

Element objects are using the Node interface, therefore all Elements are nodes. But not all nodes are elements, for example text node.

getBoundingClientrect() is only available for Element and Range objects.

So basically what you have to do, check which type of node focusNode will return.
Is it an Element? Nice, getBoundingClientRect() should be already available.
If not, and that's probably why you posted this question, you could find the closest element. Most probably the parentElement.

Just an example below in case you go with the parentElement

// get the node, in my case it's a text node
const textNode = window.getSelection().focusNode;

let position = null;

// check node type
if (textNode.nodeType === Node.ELEMENT_NODE) {
  // it's an element, so you can use getBoundingClientRect
  position = textNode.getBoundingClientRect();
}
else {
  // it's something else, so we want an element
  const parentElement = textNode.parentElement();
  position = parentElement.getBoundingClientRect();
}

Note 1:
Using the parentElement may result in wrong coordinates, as the text node can be smaller in size than the element containing the text node. padding, margin and border can cause this.

Note 2:
There's also this answer, where document.createRange() is used in order to get position of a text node. This didn't work for me, but I'm sure I just did it wrong. So it might be helpful for you as well

Alex Berger
  • 1,357
  • 1
  • 10
  • 22
  • Ranges are a great start to the solution to this problem. Using the range.getClientReacts API along with window.scrollX and window.scrollY is quite promising. – Clement Hoang Dec 15 '22 at 06:11