Ustaw pozycję kursora klawiatury w polu tekstowym html

173

Czy ktoś wie, jak przesunąć kursor klawiatury w polu tekstowym do określonej pozycji?

Na przykład, jeśli pole tekstowe (np. Element wejściowy, a nie obszar tekstowy) ma 50 znaków i chcę umieścić daszek przed znakiem 20, jak mam się do tego zabrać?

Jest to w odróżnieniu od tego pytania: jQuery Ustaw pozycję kursora w obszarze tekstowym , co wymaga jQuery.

jonhobbs
źródło

Odpowiedzi:

205

Fragment z ustawienia karetki klawiatury Josha Stodola Pozycja w polu tekstowym lub TextArea z JavaScriptem

Ogólna funkcja, która pozwoli ci wstawić kursor w dowolnym miejscu pola tekstowego lub obszaru tekstowego:

function setCaretPosition(elemId, caretPos) {
    var elem = document.getElementById(elemId);

    if(elem != null) {
        if(elem.createTextRange) {
            var range = elem.createTextRange();
            range.move('character', caretPos);
            range.select();
        }
        else {
            if(elem.selectionStart) {
                elem.focus();
                elem.setSelectionRange(caretPos, caretPos);
            }
            else
                elem.focus();
        }
    }
}

Pierwszym oczekiwanym parametrem jest identyfikator elementu, do którego chcesz wstawić kursor klawiatury. Jeśli elementu nie można znaleźć, nic się nie stanie (oczywiście). Drugim parametrem jest indeks pozycji daszka. Zero umieści kursor klawiatury na początku. Jeśli podasz liczbę większą niż liczba znaków w wartości elementu, na końcu umieści kursor klawiatury.

Testowane na IE6 i nowszych, Firefox 2, Opera 8, Netscape 9, SeaMonkey i Safari. Niestety w Safari nie działa w połączeniu ze zdarzeniem onfocus).

Przykład użycia powyższej funkcji, aby zmusić kursor klawiatury do przeskoczenia na koniec wszystkich obszarów tekstowych na stronie, gdy otrzymają fokus:

function addLoadEvent(func) {
    if(typeof window.onload != 'function') {
        window.onload = func;
    }
    else {
        if(func) {
            var oldLoad = window.onload;

            window.onload = function() {
                if(oldLoad)
                        oldLoad();

                func();
            }
        }
    }
}

// The setCaretPosition function belongs right here!

function setTextAreasOnFocus() {
/***
 * This function will force the keyboard caret to be positioned
 * at the end of all textareas when they receive focus.
 */
    var textAreas = document.getElementsByTagName('textarea');

    for(var i = 0; i < textAreas.length; i++) {
        textAreas[i].onfocus = function() {
            setCaretPosition(this.id, this.value.length);
        }
    }

    textAreas = null;
}

addLoadEvent(setTextAreasOnFocus);
Ta01
źródło
4
if(elem.selectionStart)przerywa się, gdy selectionStart ma wartość 0, jak również wskazała odpowiedź jhnns.
mpartel
1
To nie działa na mnie. Kiedy klikam faktyczne pole tekstowe, oczekuję, że pozycja kursora będzie na początku. Sprawdź moje skrzypce jsfiddle.net/khx2w
elad.chen
Funkcja setCaretPosition działa dobrze. Jednak funkcja addActionHandler nie. Ale nawet bez tego nie mogłem ustawić kursora na fokus. Najprawdopodobniej dzieje się tak dlatego, że przeglądarka sama ustawia położenie kursora na podstawie pozycji kliknięcia. Z tego, co wiem, nie ma sposobu na obejście tego, ale mogę się całkowicie mylić.
GJK,
Działa w IE9, FF25, ale nie w Chrome 30. Lepsze niż żadne!
Umber Ferrule
Mam elem.value = elem.value.replace(/^9/g,'+79')w kodzie. Na OperaMINI kursor po +. ta funkcja nie pomaga
eri
52

Link w odpowiedzi jest uszkodzony, ten powinien działać (wszystkie kredyty idą na blog.vishalon.net ):

http://snipplr.com/view/5144/getset-cursor-in-html-textarea/

W przypadku ponownego zgubienia kodu, oto dwie główne funkcje:

function doGetCaretPosition(ctrl)
{
 var CaretPos = 0;

 if (ctrl.selectionStart || ctrl.selectionStart == 0)
 {// Standard.
  CaretPos = ctrl.selectionStart;
 }
 else if (document.selection)
 {// Legacy IE
  ctrl.focus ();
  var Sel = document.selection.createRange ();
  Sel.moveStart ('character', -ctrl.value.length);
  CaretPos = Sel.text.length;
 }

 return (CaretPos);
}


function setCaretPosition(ctrl,pos)
{
 if (ctrl.setSelectionRange)
 {
  ctrl.focus();
  ctrl.setSelectionRange(pos,pos);
 }
 else if (ctrl.createTextRange)
 {
  var range = ctrl.createTextRange();
  range.collapse(true);
  range.moveEnd('character', pos);
  range.moveStart('character', pos);
  range.select();
 }
}
wieczny
źródło
1
+1 dla funkcji podstawowych, chociaż trzeba wprowadzić pewne poprawki . Liczbę wierszy należy odjąć od „pos”, gdy stosuje się metodę zakresu.
Rob W
36

Ponieważ naprawdę potrzebowałem tego rozwiązania, a typowe rozwiązanie podstawowe ( skoncentruj dane wejściowe - a następnie ustaw wartość równą sobie ) nie działa w różnych przeglądarkach , spędziłem trochę czasu na poprawianiu i edytowaniu wszystkiego, aby działało. Opierając się na @ kd7 , oto co wymyśliłem.

Cieszyć się! Działa w IE6 +, Firefox, Chrome, Safari, Opera

Technika pozycjonowania kursora w różnych przeglądarkach (przykład: przesuwanie kursora do KONIEC)

// ** USEAGE ** (returns a boolean true/false if it worked or not)
// Parameters ( Id_of_element, caretPosition_you_want)

setCaretPosition('IDHERE', 10); // example

Mięso i ziemniaki to w zasadzie setCaretPosition @ kd7 , z największą zmianą w firefoxie, if (el.selectionStart || el.selectionStart === 0)że selectionStart zaczyna się od 0 , co oczywiście zmienia się w wartość Fałsz, więc tam się psuje.

W chrome największym problemem było to, że samo podanie go .focus()nie wystarczyło (ciągle wybierał CAŁY tekst!) Dlatego el.value = el.value;przed wywołaniem naszej funkcji ustawiliśmy wartość samą w sobie , a teraz ma ona uchwyt i pozycję z wejście do użycia selectionStart .

function setCaretPosition(elemId, caretPos) {
    var el = document.getElementById(elemId);

    el.value = el.value;
    // ^ this is used to not only get "focus", but
    // to make sure we don't have it everything -selected-
    // (it causes an issue in chrome, and having it doesn't hurt any other browser)

    if (el !== null) {

        if (el.createTextRange) {
            var range = el.createTextRange();
            range.move('character', caretPos);
            range.select();
            return true;
        }

        else {
            // (el.selectionStart === 0 added for Firefox bug)
            if (el.selectionStart || el.selectionStart === 0) {
                el.focus();
                el.setSelectionRange(caretPos, caretPos);
                return true;
            }

            else  { // fail city, fortunately this never happens (as far as I've tested) :)
                el.focus();
                return false;
            }
        }
    }
}
Mark Pieszak - Trilon.io
źródło
@mcpDESIGNS Próbuję użyć tej funkcji, gdy fokus jest ustawiony na wejściu tekstowym, ale nic nie osiągam. Czy mógłbyś pomóc w zastosowaniu tej funkcji przy użyciu czystego JavaScript?
elad.chen
@ elad.chen Czy próbujesz umieścić je na końcu pola tekstowego, gdy tylko się na nim skupią?
Mark Pieszak - Trilon.io
@mcpDESIGNS Chcę umieścić kursor na początku pola, gdy tylko element zostanie skupiony. Zobacz skrzypce: jsfiddle.net/KuLTU/3
elad.chen
@ elad.chen Przepraszamy za szaloną spóźnioną odpowiedź! Po prostu zmień to wydarzenie na .onclickzamiast w .onfocusramach funkcji search_field_focus
Mark Pieszak - Trilon.io
2
el.value = el.value; [...] if(el !== null)- Zamieniłbym te dwie linie. Jeśli eljest null, el.value = el.valuezakończy się niepowodzeniem, więc ta linia powinna znajdować się wewnątrz if.
BackSlash
21

Poprawiłem trochę odpowiedź kd7, ponieważ elem.selectionStart oceni jako false, gdy selectionStart będzie przypadkowo równa 0.

function setCaretPosition(elem, caretPos) {
    var range;

    if (elem.createTextRange) {
        range = elem.createTextRange();
        range.move('character', caretPos);
        range.select();
    } else {
        elem.focus();
        if (elem.selectionStart !== undefined) {
            elem.setSelectionRange(caretPos, caretPos);
        }
    }
}
Johannes Ewald
źródło
5

Znalazłem łatwy sposób na naprawienie tego problemu, przetestowany w IE i Chrome:

function setCaret(elemId, caret)
 {
   var elem = document.getElementById(elemId);
   elem.setSelectionRange(caret, caret);
 }

Przekaż identyfikator pola tekstowego i pozycję kursora do tej funkcji.

Iam_NSA
źródło
3

Jeśli chcesz skupić się na jakimś polu tekstowym, a Twoim jedynym problemem jest to, że cały tekst zostanie podświetlony, podczas gdy chcesz, aby daszek znajdował się na końcu, w tym konkretnym przypadku możesz użyć tej sztuczki, aby ustawić wartość pola tekstowego na siebie po fokusie:

$("#myinputfield").focus().val($("#myinputfield").val());
manish_s
źródło
2
<!DOCTYPE html>
<html>
<head>
<title>set caret position</title>
<script type="application/javascript">
//<![CDATA[
window.onload = function ()
{
 setCaret(document.getElementById('input1'), 13, 13)
}

function setCaret(el, st, end)
{
 if (el.setSelectionRange)
 {
  el.focus();
  el.setSelectionRange(st, end);
 }
 else
 {
  if (el.createTextRange)
  {
   range = el.createTextRange();
   range.collapse(true);
   range.moveEnd('character', end);
   range.moveStart('character', st);
   range.select();
  }
 }
}
//]]>
</script>
</head>
<body>

<textarea id="input1" name="input1" rows="10" cols="30">Happy kittens dancing</textarea>

<p>&nbsp;</p>

</body>
</html>
DIpak
źródło
2
function SetCaretEnd(tID) {
    tID += "";
    if (!tID.startsWith("#")) { tID = "#" + tID; }
    $(tID).focus();
    var t = $(tID).val();
    if (t.length == 0) { return; }
    $(tID).val("");
    $(tID).val(t);
    $(tID).scrollTop($(tID)[0].scrollHeight); }
Keith Cromm
źródło
Uncaught TypeError: Object [object HTMLInputElement] nie ma metody „startedWith”
bobpaul
1
@bobpaul: tIDpowinno być identyfikatorem elementu, a nie samym obiektem elementu. Jeśli przekazujesz obiekt element, możesz po prostu usunąć 2 pierwsze linie w tej metodzie i zadziała.
awe
2

Naprawiłbym warunki jak poniżej:

function setCaretPosition(elemId, caretPos)
{
 var elem = document.getElementById(elemId);
 if (elem)
 {
  if (typeof elem.createTextRange != 'undefined')
  {
   var range = elem.createTextRange();
   range.move('character', caretPos);
   range.select();
  }
  else
  {
   if (typeof elem.selectionStart != 'undefined')
    elem.selectionStart = caretPos;
   elem.focus();
  }
 }
}
Alexander Gavriliuk
źródło