简体   繁体   中英

Get caret position coordinates relative to the window (x,y)

Abstract

I would like to get the window position (in pixels) of the caret (when a user start typing).

Full story

There's a multi-line contentEditable element with complex HTML structure inside of it.
When a user start typing anywhere inside it, on the first keystroke I would like to place an absolute positioned element below the caret. It is imperative that the newly added element will be injected into the <body> tag and not as a DOM node within the contentEditable element.

Therefor I require the exact global coordinates of the caret. I will be clear that there is no text selection.
Selection is irrelevant here and even unlikely.

My code

Normally a question should include some code the OP had tried & requires assistance with, but in this case I am all out of ideas. The input DOM event does not expose the coordinates. I will at least provide the end result of what I'm after:

 .info{ border: 1px solid gold; padding: 8px; background: rgba(255,255,224, .8); position: absolute; z-index: 9999; max-width: 180px; }
 <h2>contentEditable:</h2> <div contentEditable> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <strong>Ut enim ad minim veniam</strong>, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. </p> <p> Imagine the caret is somewhere here and the info element is right under it... <div>reprehenderit <em>in</em> voluptate</div> velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt <small>mollit anim</small> id est laborum. </p> </div> <div class='info' style='top:150px; left:60px;'>Extra info with a long list of some content goes here</div>


Disclaimer:

I've done quite a bit of digging on the matter but unfortunately could not find an answer. Some questions seem similar but looking deeper, they are not at all, and some are extremely old & obsolete

Thank you!

After some more digging, I came about a Gist file which did exactly what I wanted,
so here is a working about which I've tweaked a bit:

 /** * Get the caret position, relative to the window * @returns {object} left, top distance in pixels */ function getCaretGlobalPosition(){ const r = document.getSelection().getRangeAt(0) const node = r.startContainer const offset = r.startOffset const pageOffset = {x:window.pageXOffset, y:window.pageYOffset} let rect, r2; if (offset > 0) { r2 = document.createRange() r2.setStart(node, (offset - 1)) r2.setEnd(node, offset) rect = r2.getBoundingClientRect() return { left:rect.right + pageOffset.x, top:rect.bottom + pageOffset.y } } } /////////////////[ DEMO ]\\\\\\\\\\\\\\\\\\\\ const contenteditable = document.querySelector('[contenteditable]') const infoElm = document.querySelector('.info') contenteditable.addEventListener('input', onInput) function onInput(){ const caretGlobalPosition = getCaretGlobalPosition() infoElm.style.cssText = `top:${caretGlobalPosition.top}px; left:${caretGlobalPosition.left}px;` }
 .info{ border: 1px solid gold; padding: 8px; background: rgba(255,255,224, .8); position: absolute; z-index: 9999; max-width: 180px; display:none; }.info[style]{ display:block; }
 <h2>Place caret somewhere and type:</h2> <div contenteditable> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <strong>Ut enim ad minim veniam</strong>, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. </p> <h2> Imagine the caret is somewhere here and the info element is right under it... <div>reprehenderit <em>in</em> voluptate</div> velit esse cillum dolore eu fugiat f nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt <small>mollit anim</small> id est laborum. </h2> </div> <div class='info'>Extra info with a long list of some content goes here</div>


Another solution which I've found: https://github.com/component/textarea-caret-position

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM