Get caret coordinates on a contenteditable div through javascript.
Asked Answered
P

4

18

I've been searching a lot but i could't find a way to get (X,Y) coordinates for the caret on a content editable div,there's a lot of content on the web about this,but the problem none of the pages i found get the coordinates according to the top of the div,so my question in a simpler way is:

How can i get the (X,Y) coordinates of the caret on a contenteditable div,but the Y coordinate must be calculated according to the top of the div and not from the top of the visible part of the page?

Note 1: I need specially the Y coordinate.

Note 2: I can only use pure javascript,no JQUERY.

My way:

I haven't found a direct way to do this,so as a workaround i thought on getting the Y coordinate according to the visible part of the page and the hidden part of the Div and sum the results(I'm currently working on this but i getting no luck!).

Psychognosis answered 10/6, 2013 at 3:56 Comment(9)
This is a duplicate of #6846730 - you just need to subtract div position from returned coordinates.Joacimah
No it's no a duplicate question.The accepted answer does not answer my question.I need to get coordinates even if a part of the DIV is hidden.Psychognosis
Its not a duplicateDriving
What do you mean by "(X,Y) coordinates for the caret"? Coordinates in pixels? Caret has height at least, so what Y coordinate would you like to get?Genera
I want position at each instance when I wrote in an ContentediatbleDriving
If part of the div is hidden as you say, does the height need to ignore the hidden portion of the div?Grath
no it shouldnotDriving
Related: #16302576Kleinstein
Maybe you should take a look at ichord.github.io/Caret.js It seems to use jQuery but maybe you can dig into their code ;)Kleinstein
A
13

try this:

var selection = window.getSelection(),
    range = selection.getRangeAt(0),
    rect = range.getClientRects()[0];

in the rect var you should find the position:

rect.left -> for the x coordinate rect.top -> for the y coordinate

there is also rect.width and rect.height. In case the user has some text selected rect.width will be >0.

Archive answered 21/10, 2019 at 9:43 Comment(2)
my client rects have a length of 0Nonentity
Slightly weirdly, rect.width can be > 0 if the caret is at the end of a line too. The selection seems to contain the "virtual" newline added by wrapping the text. So a better way of checking if there's text selected is to see if the start and end containers and offsets are both equal. Not massively relevant, but curious!Necrosis
P
10
  1. get selection and range

     var sel = window.getSelection();
     var range = sel.getRangeAt(0);
    
  2. insert collapsed div

     var div = document.createElement(...)
     range.insertNode(div)
    
  3. get div coordinates

  4. remove the div
Paedogenesis answered 19/5, 2017 at 8:28 Comment(1)
I had to combine this with the below answer and got getClientRects() to work on the temp div.Nonentity
T
0

to find on (X,Y) coordinate and using pure javascript, this function I found may do the trick: in this Source you will find all explanation about their process (the code below is taken from the same source):

function getPosition(el) {
  var xPos = 0;
  var yPos = 0;

  while (el) {
    if (el.tagName == "BODY") {
      // deal with browser quirks with body/window/document and page scroll
      var xScroll = el.scrollLeft || document.documentElement.scrollLeft;
      var yScroll = el.scrollTop || document.documentElement.scrollTop;

      xPos += (el.offsetLeft - xScroll + el.clientLeft);
      yPos += (el.offsetTop - yScroll + el.clientTop);
    } else {
      // for all other non-BODY elements
      xPos += (el.offsetLeft - el.scrollLeft + el.clientLeft);
      yPos += (el.offsetTop - el.scrollTop + el.clientTop);
    }

    el = el.offsetParent;
  }
  return {
    x: xPos,
    y: yPos
  };
}
Touzle answered 16/9, 2016 at 13:37 Comment(2)
can you provide a any example on jsfiddleDriving
I need it in a content editable I have tried this code beforeDriving
I
-1

try this http://plnkr.co/edit/T2S7sKByTIesEVC6R8jQ?p=preview

document.addEventListener("DOMContentLoaded", function(event) { 
  var pointer = document.querySelector('#marker')
  function checkCaret() {
    if(document.getSelection()) {
      if(document.getSelection().baseNode) {
        var position = document.getSelection().baseNode.parentNode.getBoundingClientRect()
        pointer.style.top = position.top + 'px'
      }
    }
  }
  setInterval(checkCaret, 500)
});
Immediacy answered 15/9, 2016 at 19:30 Comment(1)
"Note 1: I need specially the Y coordinate." it gives y coordinateImmediacy

© 2022 - 2024 — McMap. All rights reserved.