Html metin kutusunda klavye işaretleme konumunu ayarlama


173

Bir metin kutusundaki klavye işaretini belirli bir konuma nasıl taşıyacağını bilen var mı?

Örneğin, bir metin kutusu (örn. Metin alanı değil, giriş öğesi) 50 karakter içeriyorsa ve imleci 20 karakterinden önce konumlandırmak istiyorsam, nasıl devam edeceğim?

Bu sorudan farklıdır: jQuery jQuery gerektiren Metin Alanında İmleç Konumunu Ayarla .

Yanıtlar:


205

Josh Stodola'nın Metin Kutusu veya Javascript ile TextArea içindeki klavye düzeltme işareti Konumunu Ayarlama

İmleci dilediğiniz metin kutusunun veya metin alanının herhangi bir yerine yerleştirmenize olanak tanıyan genel bir işlev:

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();
        }
    }
}

Beklenen ilk parametre, klavye işaretini eklemek istediğiniz öğenin kimliğidir. Eleman bulunamadığı takdirde hiçbir şey olmayacak (belli ki). İkinci parametre, düzeltme konumu dizinidir. Sıfır klavyenin başlangıcını başlangıca yerleştirir. Öğeler değerindeki karakter sayısından daha büyük bir sayı iletirseniz, klavye işaretini sonuna koyar.

IE6 ve üstü, Firefox 2, Opera 8, Netscape 9, SeaMonkey ve Safari'de test edildi. Ne yazık ki Safari'de onfocus olayıyla birlikte çalışmaz).

Klavye işlevini odak aldıklarında sayfadaki tüm metinlerin sonuna atlamaya zorlamak için yukarıdaki işlevi kullanma örneği:

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);

4
if(elem.selectionStart)selectionStart, jhnns'ın cevabında da belirtildiği gibi 0 olduğunda kırılır.
mpartel

1
Bu benim için işe yaramıyor. Gerçek metin kutusunu tıklattığımda, düzeltme konumu konumunun başlangıçta olmasını bekliyorum. Benim keman jsfiddle.net/khx2w
elad.chen

SetCaretPosition işlevi gayet iyi çalışıyor. Ancak addActionHandler işleviniz bunu yapmaz. Ama bu olmadan bile, imlecin odakta hareket etmesini sağlayamadım. Büyük olasılıkla, tarayıcının imlecin konumunu, tıklatmanın konumuna göre ayarlamasıdır. Etrafında söyleyebileceğim bir yol yok gibi görünüyor, ama tamamen yanlış olabilirdim.
GJK

IE9, FF25'te çalışır, ancak Chrome 30'da çalışmaz.
Umber Yüksük

Kodum var elem.value = elem.value.replace(/^9/g,'+79'). OperaMINI imlecinden sonra +. bu işlev yardımcı olmaz
eri

52

Yanıttaki bağlantı koptu, bu işe yaramalı (tüm krediler blog.vishalon.net'e gidiyor ):

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

Kod tekrar kaybolursa, iki temel işlev şunlardır:

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();
 }
}

1
Temel işlevler için +1, ancak bazı ayarlamalar yapılmalıdır . Aralık yöntemi kullanılırken satır sayısı "pos" dan çıkarılmalıdır.
Rob W

36

Gerçekten bu çözüme gerçekten ihtiyaç duyduğumdan ve tipik temel çözüm ( girişe odaklan - sonra değeri kendisine eşit olarak ayarla ) çapraz tarayıcı çalışmadığından , çalışmasını sağlamak için her şeyi ayarlayıp düzenlemek için biraz zaman harcadım. @ Kd7 kodunun üzerine gelince işte burada bulduğum şey.

Zevk almak! IE6 +, Firefox, Chrome, Safari, Opera'da çalışır

Çapraz tarayıcı düzeltme konumu konumlandırma tekniği (örnek: imleci END konumuna taşıma)

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

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

Et ve patates temelde @ KD7 'ın setCaretPosition, en büyük çimdik varlık ile if (el.selectionStart || el.selectionStart === 0), içinde ateş SelectionStart de başlıyor 0 orada kırılma bu yüzden tabii boolean, False olarak çeviriyor, hangi.

Chrome'da en büyük sorun, sadece vermenin .focus()yeterli olmamasıydı (metnin TÜMÜNÜ seçmeye devam etti!) Bu nedenle, el.value = el.value;işlevimizi çağırmadan önce kendisinin değerini kendimize ayarladık ve şimdi seçimi kullanmak için giriş .

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;
            }
        }
    }
}

@mcpDESIGNS Metin girişine odaklanıldığında bu işlevi kullanmaya çalışıyorum, ama hiçbir yere gitmiyorum, lütfen saf javascript kullanarak bu işlevi uygulamanıza yardımcı olabilir misiniz?
elad.chen

@ elad.chen Bunları, odaklandıkları anda metin kutusunun sonuna yerleştirmeye çalışıyorsunuz?
Mark Pieszak - Trilon.io

@mcpDESIGNS Öğe odaklanır odaklanmaz imleci alanın başına yerleştirmek istiyorum. Kemanı görün: jsfiddle.net/KuLTU/3
elad.chen

@ elad.chen Çılgın geç cevap için özür dilerim! Yalnızca bu etkinliği .onclick.onfocus
arama_çalışma_fokus

2
el.value = el.value; [...] if(el !== null)- Bu iki çizgiyi değiştirirdim. Eğer elnull, el.value = el.valuebaşarısız olur, böylece hat içeride olmalıdır if.
BackSlash

21

Elem.selectionStart, selectionStart tesadüfen 0 olduğunda false olarak değerlendireceğinden kd7'nin cevabını biraz ayarladım.

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);
        }
    }
}

5

IE ve Chrome'da test edilen bu sorunu düzeltmenin kolay bir yolunu buldum:

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

Metin kutusu kimliğini ve düzeltme konumunu bu işleve iletin.


3

Bazı metin kutularına odaklanmanız gerekiyorsa ve tek sorununuz metnin tamamının vurgulanmasıdır, oysa sonunda düzeltme işareti olmasını istiyorsanız, o zaman belirli bir durumda, odaktan sonra metin kutusu değerini kendiniz ayarlama hilesini kullanabilirsiniz:

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

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>

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); }

Yakalanmayan TypeError: [object HTMLInputElement] nesnesinin 'startsWith' yöntemi yok
bobpaul

1
@bobpaul: tIDelement nesnesinin kendisi değil, elementin kimliği olmalıdır. Eleman nesnesini geçiyorsanız, bu yöntemdeki ilk 2 satırı kaldırabilirsiniz; bu işe yarayacaktır.
korku

2

Aşağıdaki gibi koşulları düzeltmek istiyorum:

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();
  }
 }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.