Open giorgio79 opened 10 years ago
negative. i think it's easier if you use contenteditable since you can do select range i believe. textareas and inputs don't have that luxury
It can easily support it with a few changes and adding something like this, right at the beginning of the function:
function getCaretCoordinates(element, position, options) {
/*
isBrowser check..
*/
if (!element) {
return getCaretCoordinates(document.activeElement || document.documentElement, position, options);
}
if (!element.isConnected) // in case of getCaretCoordinates(document.createElement('input'));
return {
top: 0,
left: 0,
height: 0,
node: element
}
if (options && options.absolute) {
let relative = getCaretCoordinates(element, position),
erect = element.getBoundingClientRect();
return {
top: erect.top + relative.top,
left: erect.left + relative.left,
height: relative.height, // remember kids, drugs are bad
node: element
}
}
let specials = ~['INPUT', 'TEXTAREA'].indexOf(element.nodeName);
if (position == null || !specials) {
if (specials) {
return getCaretCoordinates(element, element.selectionDirection == 'forward' ? element.selectionEnd : element.selectionStart);
} else {
if (window.getSelection().rangeCount) {
let range = window.getSelection().getRangeAt(0),
rect = range.getBoundingClientRect();
// using the start or endcontainer is... uhm yeah... difficult...? :D
let height = range.startContainer.nodeType == 1 ? getComputedStyle(range.startContainer).lineHeight : getComputedStyle(range.startContainer.parentNode).lineHeight;
if (isNaN(height)) {
let node = range.startContainer;
if (range.startContainer.nodeType != 1) {
node = node.parentNode;
}
let current = node.style.lineHeight;
node.style.lineHeight = '1em';
height = parseInt(getComputedStyle(node).lineHeight);
node.style.lineHeight = current != null ? current : '';
if (!node.getAttribute('style').length) { // clean up if empty
node.removeAttribute('style');
}
}
let erect = //thihihi
element.getBoundingClientRect();
return {
top: rect.top - erect.top,
left: rect.left - erect.left,
height: height,
node: element
}
} else {
return {
top: 0,
left: 0,
height: 0,
node: element
}
}
}
}
/*
... rest of the code
*/
}
This is compatible with all mayor browsers (add this range check for IE8, if you wanna support it).
One function that works for both types and returns the same output, is be really helpful. 👍
With this changes you could do:
getCaretPosition(); // returns the caret position, depending on the activeElement if any.
getCaretPosition(element); // returns the caret position inside that element
getCaretPosition(element, index); // same as before
getCaretPosition(null, null, { position: absolute }); // returns the absolute position of the caret depending on the current selected element
Greetings
I notice the readme mentions textarea only.