简体   繁体   中英

Find character position based on mouse move in a input field

I need to find the position of the character in the input field based on the mouse movement.

for example: if the input field has value as 'abcde' and I am moving my mouse on the character 'a' then the position will be 1, 'b' will provide 2 and so on for the other characters.

I did find few examples that works with the selectionStart etc., but they work only when the caret is placed at some position and then find the placed position.

What I am looking for is - that there may / may not be click done in the input field, regardless when the mouse is moving on the characters - I be able to know the position of the character, where mouse hovered upon.

I haven't come across any idea how I can convert the mouse coordinates respectively into character position. Are there any such javascript API's?

Any help / pointers / ideas are much appreciated.

Update

My end goal is automatically move the caret as the drag is happening over the contenteditable div. I found a following link asking for the similar problem - but there is no solution suggested so far.

caret auto move - https://stackoverflow.com/questions/12397792/update-caret-position-of-input-and-insert-text-on-drop-event/53660415#53660415

I have also added another example to show the different behavior of native drag vs. jQuery drag. I am using jQuery draggable that does not support auto drag of caret.

https://jsfiddle.net/VidushiGupta/7warczfy/

Jquery: You could try the Caret plugin (I'm not sure this meets your needs though) You can read the jquery page , but it's not very informative!

Javascript solutions:

I looked around for pre-existing solutions but regarding the hover/mouseover found only one potential adaptable solution. This code is not mine, it's adapted from a public fiddle I found by Carlos Delgado (I adapted so that if you hover on the "Show position" text, it will display the cursor position). It also demonstrates the use of selectionStart and selectionEnd , so start and end positions are displayed if text is selected. If you move the cursor forward or back with the arrow keys, and then hover again, the updated cursor position will show.

Also, here's a shorter [alternative] version (without the start/end etc)

 function getInputSelection(el) { var start = 0, end = 0, normalizedValue, range, textInputRange, len, endRange; if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") { start = el.selectionStart; end = el.selectionEnd; } else { range = document.selection.createRange(); if (range && range.parentElement() == el) { len = el.value.length; normalizedValue = el.value.replace(/\\r\\n/g, "\\n"); // Create a working TextRange that lives only in the input textInputRange = el.createTextRange(); textInputRange.moveToBookmark(range.getBookmark()); // Check if the start and end of the selection are at the very end // of the input, since moveStart/moveEnd doesn't return what we want // in those cases endRange = el.createTextRange(); endRange.collapse(false); if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) { start = end = len; } else { start = -textInputRange.moveStart("character", -len); start += normalizedValue.slice(0, start).split("\\n").length - 1; if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) { end = len; } else { end = -textInputRange.moveEnd("character", -len); end += normalizedValue.slice(0, end).split("\\n").length - 1; } } } } return { start: start, end: end }; } document.getElementById("trigger").addEventListener("mouseover", function() { var input = document.getElementById("texto"); var inputContent = input.value.length; // You may want to focus the textbox in case it's not input.focus(); var result = getInputSelection(input); var resultSpan = document.getElementById("result"); if (result.start == result.end) { resultSpan.innerHTML = "No text selected. Position of cursor is " + result.start + " of " + inputContent; } else { resultSpan.innerHTML = "You've selected text (" + result.start + " to " + result.end + ") from a total length of " + inputContent; } }, false);
 #trigger{background:#ff8890;}
 <p> Get the cursor position in a textarea or a text input or the selected text. </p><br> <textarea id="texto"></textarea><br><br> <input type="text" id="trigger" value="Show Position" size="10" /><br><br> <span id="result"></span>

This solution may also work: It shows the position in the console (perhaps that's preferable?). You could adjust that if needsbe.

 document.getElementById('showpos').addEventListener('mouseenter', e => { console.log('Caret at: ', e.target.selectionStart) })
 <input id="showpos" />

Hope these ideas help

Rachel

Try this function, giving it the mouse move event's pageX and pageY values:

/**
 * Get the closest caret position to the given page coordinates.
 * @param x {int}
 * @param y {int}
 * @param doc {Document}
 * @return {[Node, int]} Node with the caret and offset within that node. */
function fromCoordinates(x, y, doc=document) {

    // Firefox
    if (doc.caretPositionFromPoint) {
        let caretPosition = doc.caretPositionFromPoint(x, y);
        if (caretPosition)
            return [caretPosition.offsetNode, caretPosition.offset];
    }

    // All others
    if (doc.caretRangeFromPoint) {
        let range = doc.caretRangeFromPoint(x, y);
        if (range)
            return [range.startContainer, range.startOffset];
    }

    return null;
}

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