(x, y) coordinates of the caret in a textarea or input type='text'
npm install textarea-caretGet the top and left coordinates of the caret in a or, in pixels. Useful for textarea autocompletes like
GitHub or Twitter, or for single-line autocompletes like the name drop-down
in Twitter or Facebook's search or the company dropdown on Google Finance.
How it's done: a faux Check out the JSFiddle * supports `` document.querySelector('textarea').addEventListener('input', function () { * element * position The function returns a caret coordinates object of the form {top: , left: , height: } * Off-by-one edge cases with spaces at the end of lines in None. * Add tests. For the same textarea of 25 rows and 40 columns, Chrome 33, Firefox 27 and IE9 returned completely different values Chrome 33 IE 9: scrollbar looks 16px, the text itself in the text area is 224px wide Firefox 27 * Dan Dascalescu (dandv) is created off-screen and styled exactly like thetextarea or input. Then, the text of the element up to the caret is copied
into the div and a is inserted right after it. Then, the text content
of the span is set to the remainder of the text in the , in order to
faithfully reproduce the wrapping in the faux div (because wrapping can push
the currently typed word onto the next line). The same is done for theinput to simplify the code, though it makes no difference. Finally, the span's
offset within the textarea or input is returned.Demo
or the test.html.Features
s and elements
* pixel precision with any combination of paddings, margins, borders, heights vs. line-heights etc.
* keyboard, mouse support and touch support
* no dependencies whatsoever
* browser compatibility: Chrome, Safari, Firefox (despite two bugs it has), Opera, IE9+
* supports any font family and size, as well as text-transforms
* not confused by horizontal or vertical scrollbars in the textarea
* supports hard returns, tabs (except on IE) and consecutive spaces in the text
* correct position on lines longer than the columns in the text area
* no problem getting the correct position when the input text is scrolled (i.e. the first visible character is no longer the first in the text)
* no "ghost" position in the empty space at the end of a line when wrapping long words in a
* RTL (right-to-left) supportExample
js
var getCaretCoordinates = require('textarea-caret');
var caret = getCaretCoordinates(this, this.selectionEnd);
console.log('(top, left, height) = (%s, %s, %s)', caret.top, caret.left, caret.height);
})
`API
$3
is the DOM element, either an or textarea is an integer indicating the location of the caret. Most often you'll want to pass this.selectionStart or this.selectionEnd. This way, the library isn't opinionated about what the caret is., where:top
* and left are the offsets in pixels from the upper-left corner of the element and (or presumably the upper-right, but this hasn't been tested), andheight
* is the height of the caret - useful to calculate the bottom of the caret.Known issues
Dependencies
TODO
* Consider adding IE-specific code if it avoids the necessity of creating the mirror div and might fix #14.
* ~~Test IE8 support with currentStyle~~.Implementation notes
for computed.width, textarea.offsetWidth, and textarea.clientWidth. Here, computed is getComputedStyle(textarea):
* computed.width : "240px" = the text itself, no borders, no padding, no scrollbarstextarea.clientWidth
* : 280 = computed.width + padding-left + padding-righttextarea.offsetWidth
* : 327 = clientWidth + scrollbar (15px) + border-left + border-right
* computed.width: "241.37px" = text only + sub-pixel scrollbar? (1.37px)textarea.clientWidth
* : 264textarea.offsetWidth
* : 313
* computed.width: "265.667px"textarea.clientWidth
* : 249 - the only browser where textarea.clientWidth < computed.widthtextarea.offsetWidth`: 338
* Contributors
* Jonathan Ong (jonathanong)