Domanda jQuery Imposta la posizione del cursore nell'area di testo


Come si imposta la posizione del cursore in un campo di testo usando jQuery? Ho un campo di testo con contenuto e voglio che il cursore dell'utente sia posizionato su un determinato offset quando si focalizzano sul campo. Il codice dovrebbe apparire un po 'come questo:

$('#input').focus(function() {
  $(this).setCursorPosition(4);
});

Come sarebbe l'implementazione della funzione setCursorPosition? Se avessi un campo di testo con il contenuto abcdefg, questa chiamata determinerebbe il posizionamento del cursore come segue: abcd ** | ** efg.

Java ha una funzione simile, setCaretPosition. Esiste un metodo simile per javascript?

Aggiornamento: ho modificato il codice CMS per lavorare con jQuery come segue:

new function($) {
  $.fn.setCursorPosition = function(pos) {
    if (this.setSelectionRange) {
      this.setSelectionRange(pos, pos);
    } else if (this.createTextRange) {
      var range = this.createTextRange();
      range.collapse(true);
      if(pos < 0) {
        pos = $(this).val().length + pos;
      }
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  }
}(jQuery);

418
2018-01-31 16:39


origine


risposte:


Ho due funzioni:

function setSelectionRange(input, selectionStart, selectionEnd) {
  if (input.setSelectionRange) {
    input.focus();
    input.setSelectionRange(selectionStart, selectionEnd);
  }
  else if (input.createTextRange) {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
}

function setCaretToPos (input, pos) {
  setSelectionRange(input, pos, pos);
}

Quindi puoi usare setCaretToPos come questo:

setCaretToPos(document.getElementById("YOURINPUT"), 4);

Esempio dal vivo con entrambi a textarea e un input, mostrando l'uso di jQuery:

function setSelectionRange(input, selectionStart, selectionEnd) {
  if (input.setSelectionRange) {
    input.focus();
    input.setSelectionRange(selectionStart, selectionEnd);
  } else if (input.createTextRange) {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
}

function setCaretToPos(input, pos) {
  setSelectionRange(input, pos, pos);
}

$("#set-textarea").click(function() {
  setCaretToPos($("#the-textarea")[0], 10)
});
$("#set-input").click(function() {
  setCaretToPos($("#the-input")[0], 10);
});
<textarea id="the-textarea" cols="40" rows="4">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</textarea>
<br><input type="button" id="set-textarea" value="Set in textarea">
<br><input id="the-input" type="text" size="40" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit">
<br><input type="button" id="set-input" value="Set in input">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

A partire dal 2016, testato e funzionante su Chrome, Firefox, IE11, anche IE8 (vedi quest'ultimo Qui; I frammenti di stack non supportano IE8).


239
2018-01-31 16:56



Ecco una soluzione jQuery:

$.fn.selectRange = function(start, end) {
    if(end === undefined) {
        end = start;
    }
    return this.each(function() {
        if('selectionStart' in this) {
            this.selectionStart = start;
            this.selectionEnd = end;
        } else if(this.setSelectionRange) {
            this.setSelectionRange(start, end);
        } else if(this.createTextRange) {
            var range = this.createTextRange();
            range.collapse(true);
            range.moveEnd('character', end);
            range.moveStart('character', start);
            range.select();
        }
    });
};

Con questo, puoi farlo

$('#elem').selectRange(3,5); // select a range of text
$('#elem').selectRange(3); // set cursor position

285
2018-05-08 18:17



Le soluzioni qui sono giuste ad eccezione del codice di estensione jQuery.

La funzione di estensione dovrebbe scorrere su ciascun elemento selezionato e ritornare this per supportare il concatenamento. Qui è il  un versione corretta:

$.fn.setCursorPosition = function(pos) {
  this.each(function(index, elem) {
    if (elem.setSelectionRange) {
      elem.setSelectionRange(pos, pos);
    } else if (elem.createTextRange) {
      var range = elem.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  });
  return this;
};

36
2017-09-06 11:55



Ho trovato una soluzione che funziona per me:

$.fn.setCursorPosition = function(position){
    if(this.length == 0) return this;
    return $(this).setSelection(position, position);
}

$.fn.setSelection = function(selectionStart, selectionEnd) {
    if(this.length == 0) return this;
    input = this[0];

    if (input.createTextRange) {
        var range = input.createTextRange();
        range.collapse(true);
        range.moveEnd('character', selectionEnd);
        range.moveStart('character', selectionStart);
        range.select();
    } else if (input.setSelectionRange) {
        input.focus();
        input.setSelectionRange(selectionStart, selectionEnd);
    }

    return this;
}

$.fn.focusEnd = function(){
    this.setCursorPosition(this.val().length);
            return this;
}

Ora puoi spostare lo stato attivo alla fine di qualsiasi elemento chiamando:

$(element).focusEnd();

21
2017-08-24 19:02



Questo ha funzionato per me su Safari 5 su Mac OSX, jQuery 1.4:

$("Selector")[elementIx].selectionStart = desiredStartPos; 
$("Selector")[elementIx].selectionEnd = desiredEndPos;

9
2017-08-26 15:51



Sto usando questo: http://plugins.jquery.com/project/jCaret


6
2018-01-18 20:20



Impostare la messa a fuoco prima di aver inserito il testo nella textarea così?

$("#comments").focus();
$("#comments").val(comments);

6
2018-01-01 09:38



Mi rendo conto che questo è un post molto vecchio, ma ho pensato che avrei dovuto offrire forse una soluzione più semplice per aggiornarlo usando solo jQuery.

function getTextCursorPosition(ele) {   
    return ele.prop("selectionStart");
}

function setTextCursorPosition(ele,pos) {
    ele.prop("selectionStart", pos + 1);
    ele.prop("selectionEnd", pos + 1);
}

function insertNewLine(text,cursorPos) {
    var firstSlice = text.slice(0,cursorPos);
    var secondSlice = text.slice(cursorPos);

    var new_text = [firstSlice,"\n",secondSlice].join('');

    return new_text;
}

Utilizzo per l'utilizzo di ctrl-enter per aggiungere una nuova riga (come in Facebook):

$('textarea').on('keypress',function(e){
    if (e.keyCode == 13 && !e.ctrlKey) {
        e.preventDefault();
        //do something special here with just pressing Enter
    }else if (e.ctrlKey){
        //If the ctrl key was pressed with the Enter key,
        //then enter a new line break into the text
        var cursorPos = getTextCursorPosition($(this));                

        $(this).val(insertNewLine($(this).val(), cursorPos));
        setTextCursorPosition($(this), cursorPos);
    }
});

Sono aperto alla critica. Grazie.

AGGIORNAMENTO: questa soluzione non consente il normale funzionamento della copia e incolla (ad esempio ctrl-c, ctrl-v), quindi dovrò modificarlo in futuro per assicurarmi che la parte funzioni di nuovo. Se hai un'idea su come farlo, per favore commenta qui, e sarò felice di provarlo. Grazie.


6
2017-12-03 20:44