ตั้งตำแหน่งแป้นคาเร็ตในกล่องข้อความ html


173

ไม่มีใครรู้วิธีย้ายแป้นคาเร็ตในกล่องข้อความไปยังตำแหน่งที่ต้องการหรือไม่?

ตัวอย่างเช่นถ้ากล่องข้อความ (เช่นอิลิเมนต์อินพุตไม่ใช่พื้นที่ข้อความ) มี 50 อักขระในนั้นและฉันต้องการวางคาเร็ตก่อนอักขระ 20 ฉันจะไปเกี่ยวกับเรื่องนี้อย่างไร

นี่คือความแตกต่างจากคำถามนี้: jQuery ตั้งตำแหน่งเคอร์เซอร์ในพื้นที่ข้อความซึ่งต้องใช้ jQuery

คำตอบ:


205

ข้อความที่ตัดตอนมาจากการตั้งค่าแป้นลูกศรของ Josh Stodola ใน Textbox หรือ TextArea ด้วย Javascript

ฟังก์ชั่นทั่วไปที่จะช่วยให้คุณแทรกเครื่องหมายรูปหมวกที่ตำแหน่งใด ๆ ของกล่องข้อความหรือ textarea ที่คุณต้องการ:

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

พารามิเตอร์แรกที่คาดหวังคือ ID ขององค์ประกอบที่คุณต้องการแทรกคาเร็ตคีย์บอร์ด หากไม่พบองค์ประกอบจะไม่มีอะไรเกิดขึ้น (ชัดเจน) พารามิเตอร์ที่สองคือดัชนี poset caret ซีโร่จะวางคาเร็ตคีย์บอร์ดไว้ที่จุดเริ่มต้น หากคุณผ่านตัวเลขที่มากกว่าจำนวนตัวอักษรในค่าองค์ประกอบมันจะวางเครื่องหมายรูปแป้นพิมพ์ที่ท้าย

ทดสอบบน IE6 ขึ้นไป, Firefox 2, Opera 8, Netscape 9, SeaMonkey และ Safari น่าเสียดายที่ Safari ไม่ทำงานร่วมกับเหตุการณ์ onfocus)

ตัวอย่างของการใช้ฟังก์ชั่นด้านบนเพื่อบังคับให้แป้นคาเร็ตเพื่อข้ามไปยังจุดสิ้นสุดของ textareas ทั้งหมดในหน้าเมื่อพวกเขาได้รับโฟกัส:

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 เป็น 0 ตามที่ชี้โดยคำตอบของ jhnns
mpartel

1
มันไม่ได้ผลสำหรับฉัน เมื่อฉันคลิกกล่องข้อความจริงฉันคาดหวังว่าตำแหน่งคาเร็ตจะอยู่ในจุดเริ่มต้น ตรวจสอบซอของฉันjsfiddle.net/khx2w
elad.chen

ฟังก์ชัน setCaretPosition ทำงานได้ดี ฟังก์ชัน addActionHandler ของคุณไม่ทำงาน แต่ถึงอย่างนั้นฉันก็ไม่สามารถเลื่อนเคอร์เซอร์ไปที่โฟกัสได้ เป็นไปได้มากว่าเป็นเพราะเบราว์เซอร์ตั้งตำแหน่งเคอร์เซอร์เองตามตำแหน่งของการคลิก ดูเหมือนจะไม่มีทางล้อมรอบจากสิ่งที่ฉันสามารถบอกได้ แต่ฉันอาจผิดอย่างสมบูรณ์
GJK

ใช้งานได้ใน IE9, FF25 แต่ไม่ใช่ Chrome 30 ดีกว่าไม่มีเลย!
Umber Ferrule

ฉันมีelem.value = elem.value.replace(/^9/g,'+79')รหัส เมื่อวันที่ OperaMINI +เคอร์เซอร์หลัง ฟังก์ชั่นนี้ใช้ไม่ได้
eri

52

ลิงก์ในคำตอบเสียหายลิงก์นี้ควรใช้งานได้ (เครดิตทั้งหมดไปที่blog.vishalon.net ):

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

ในกรณีที่รหัสหายไปอีกครั้งนี่คือหน้าที่หลักสองประการ:

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
+1 สำหรับฟังก์ชั่นฐานแม้ว่าจะปรับเปลี่ยนบางอย่างจะต้องมีการทำ จำนวนบรรทัดต้องถูกแทนที่จาก "pos" เมื่อใช้วิธีการช่วง
Rob W

36

เนื่องจากฉันต้องการโซลูชันนี้จริง ๆ และโซลูชันพื้นฐานทั่วไป ( โฟกัสอินพุต - จากนั้นตั้งค่าเท่ากับตัวเอง ) ไม่ทำงานข้ามเบราว์เซอร์ฉันใช้เวลาปรับแต่งและแก้ไขทุกอย่างเพื่อให้ทำงานได้ การสร้างโค้ดของ @ kd7นี่คือสิ่งที่ฉันคิดไว้

สนุก! ทำงานได้ใน IE6 +, Firefox, Chrome, Safari, Opera

เทคนิคการวางตำแหน่งคาเร็ตข้ามเบราว์เซอร์ (ตัวอย่าง: เลื่อนเคอร์เซอร์ไปที่ปลาย)

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

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

เนื้อสัตว์และมันฝรั่งนั้นเป็นsetCaretPosition โดย @ kd7โดยมีการบิดที่ใหญ่ที่สุดif (el.selectionStart || el.selectionStart === 0)ใน firefox selectionStart เริ่มต้นที่0ซึ่งแน่นอนว่าบูลีนจะเปลี่ยนเป็นเท็จดังนั้นมันจึงหยุดอยู่ตรงนั้น

ในโครมปัญหาที่ใหญ่ที่สุดคือการให้มัน.focus()ไม่เพียงพอ (มันเลือกข้อความทั้งหมด!) ดังนั้นเราจึงกำหนดค่าของตัวเองให้กับตัวเองel.value = el.value;ก่อนที่จะเรียกฟังก์ชั่นของเราและตอนนี้มันมีความเข้าใจ & ตำแหน่งด้วย ป้อนข้อมูลเพื่อใช้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;
            }
        }
    }
}

@mcpDESIGNS ฉันพยายามใช้ฟังก์ชั่นนี้เมื่อมีการโฟกัสที่การป้อนข้อความ แต่ฉันไม่ไปไหนคุณช่วยกรุณาใช้ฟังก์ชั่นนี้โดยใช้จาวาสคริปต์แท้ ๆ ได้ไหม?
elad.chen

@ elad.chen คุณพยายามวางตำแหน่งไว้ที่ส่วนท้ายของกล่องข้อความทันทีที่เน้นไปที่มันหรือไม่?
Mark Pieszak - Trilon.io

@mcpDESIGNS ฉันต้องการวางเคอร์เซอร์ในจุดเริ่มต้นของเขตข้อมูลทันทีที่องค์ประกอบกำลังถูกโฟกัส ดูซอ: jsfiddle.net/KuLTU/3
elad.chen

@ elad.chen ขออภัยในความล่าช้า เพียงแค่เปลี่ยนเหตุการณ์นั้นให้.onclickเป็นแทนที่จะ.onfocusอยู่ในฟังก์ชั่น
search_field_focus

2
el.value = el.value; [...] if(el !== null)- ฉันจะสลับสองบรรทัดนี้ ถ้าelเป็น null จะล้มเหลวดังนั้นเส้นที่ควรจะเป็นภายในel.value = el.value if
BackSlash

21

ฉันได้ปรับคำตอบของ kd7 เล็กน้อยเพราะ elem.selectionStart จะประเมินเป็นเท็จเมื่อ selectionStart เป็น 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);
        }
    }
}

5

ฉันพบวิธีง่ายๆในการแก้ไขปัญหานี้ทดสอบใน IE และ Chrome:

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

ผ่าน ID กล่องข้อความและตำแหน่งคาเร็ตไปยังฟังก์ชันนี้


3

หากคุณต้องการเน้นกล่องข้อความบางส่วนและปัญหาเดียวของคุณคือข้อความทั้งหมดจะถูกเน้นในขณะที่คุณต้องการให้เครื่องหมายรูปหมวกท้ายที่สุดในกรณีนั้นคุณสามารถใช้เคล็ดลับในการตั้งค่าช่องข้อความให้เป็นตัวของมันเองหลังจากโฟกัส:

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

Uncaught TypeError: Object [วัตถุ HTMLInputElement] ไม่มีเมธอด 'startsWith'
bobpaul

1
@ บ๊อบพอล: tIDควรเป็น id ขององค์ประกอบไม่ใช่วัตถุองค์ประกอบ หากคุณผ่านวัตถุองค์ประกอบคุณสามารถลบ 2 บรรทัดแรกในวิธีการนี้และมันจะทำงาน
กลัว

2

ฉันจะแก้ไขเงื่อนไขดังนี้:

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();
  }
 }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.