19

I'm using a plugin called jQuery TextRange to get the position of cursor inside a input (in my case, a textarea) and set the position too.

But now I have one thing that - I think - is harder to solve. I want know if in jQuery exist one event like "cursor position changed". What I mean is something like:

$('#my-input').on('cursorchanged', function(e){
    // My code goes here.
)};

I want to know when the cursor is moved inside the input/textarea, doesn't matter if by arrow keys or mouse click. I'm a jQuery newbie, but I think doesn't exist a event like this on jQuery, or exists?

Paladini
  • 4,522
  • 15
  • 53
  • 96

4 Answers4

23

No, there is no event like "cursor position changed".

But if you want to know if the cursor position changed, you can do something like this: tested with jquery 1.7, i tested in Ie8 and chrome

var last_position = 0;
$(document).ready(function () {
    $("#my_input").bind("keydown click focus", function() {
        console.log(cursor_changed(this));
    });
});

the console.log will return when the cursor have changed.

function cursor_changed(element) {
    var new_position = getCursorPosition(element);
    if (new_position !== last_position) {
        last_position = new_position;
        return true;
    }
        return false;
}

function getCursorPosition(element) {
    var el = $(element).get(0);
    var pos = 0;
    if ('selectionStart' in el) {
        pos = el.selectionStart;
    } else if ('selection' in document) {
        el.focus();
        var Sel = document.selection.createRange();
        var SelLength = document.selection.createRange().text.length;
        Sel.moveStart('character', -el.value.length);
        pos = Sel.text.length - SelLength;
    }
    return pos;
}
Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
Renato Prado
  • 3,770
  • 4
  • 21
  • 26
  • 2
    It doesn't seem to notice changes of the cursor position when they are caused by context menu actions (cut/paste/undo/delete). – Robert Jan 15 '14 at 00:49
  • 14
    You need to use `keyup` instead of `keydown`, otherwise the callback will pick the previous caret position instead of the next after the key event. – Fagner Brack Oct 21 '15 at 18:03
  • your click listener might not reflect the new position unless your handler which inspects the position is first wrapped in window.setTimeout() – mwag Nov 04 '18 at 20:56
  • 1
    @Robert, good point. This is solvable by watching another event - the `input` event (see [Mozilla docs](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event)). – Petr Bodnár May 03 '20 at 10:51
1

I needed something like this myself, so based on @RenatoPrado solution I've created a jQuery extension (it's on npm - jquery-position-event).

To use it you can add standard event:

var textarea = $('textarea').on('position', function(e) {
   console.log(e.position);
});

and if you want the initial value you can use:

var textarea = $('textarea').on('position', function(e) {
   console.log(e.position);
}).trigger('position');

The event also have useful column and line properties.

jcubic
  • 61,973
  • 54
  • 229
  • 402
0

In pure JS, also remembers caret position, please let me know if there're missing events.

const textarea = document.querySelector('textarea')

const storeCaretPos = () =>
  requestAnimationFrame(() =>
    localStorage.setItem('caretPos', textarea.selectionStart),
  )

textarea.oninput = textarea.onclick = textarea.oncontextmenu = storeCaretPos

textarea.onkeyup = ({ key }) => {
  if (['Arrow', 'Page', 'Home', 'End'].some(type => key.startsWith(type))) {
    storeCaretPos()
  }
}
Wenfang Du
  • 8,804
  • 9
  • 59
  • 90
-1

in React we can add an onSelect event handler for the input tag. in js it will be onselectstart https://learn.javascript.ru/selection-range#sobytiya-pri-vydelenii.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 03 '23 at 15:48