Đặt vị trí dấu bàn phím trong hộp văn bản html


173

Có ai biết làm thế nào để di chuyển bàn phím trong hộp văn bản đến một vị trí cụ thể không?

Ví dụ: nếu một hộp văn bản (ví dụ: phần tử đầu vào, không phải vùng văn bản) có 50 ký tự trong đó và tôi muốn định vị dấu mũ trước ký tự 20, tôi sẽ tìm hiểu về nó như thế nào?

Đây là điểm khác biệt so với câu hỏi này: jQuery Set Vị trí con trỏ trong Vùng văn bản , yêu cầu jQuery.

Câu trả lời:


205

Trích từ Vị trí đặt bàn phím của Josh Stodola Vị trí trong hộp văn bản hoặc TextArea bằng Javascript

Một chức năng chung sẽ cho phép bạn chèn dấu mũ vào bất kỳ vị trí nào của hộp văn bản hoặc textarea mà bạn muốn:

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

Tham số dự kiến ​​đầu tiên là ID của phần tử bạn muốn chèn dấu mũ bàn phím. Nếu phần tử không thể được tìm thấy, sẽ không có gì xảy ra (rõ ràng). Tham số thứ hai là chỉ số positon. Zero sẽ đặt caret bàn phím lúc đầu. Nếu bạn vượt qua một số lớn hơn số lượng ký tự trong giá trị phần tử, nó sẽ đặt dấu mũ bàn phím ở cuối.

Đã thử nghiệm trên IE6 trở lên, Firefox 2, Opera 8, Netscape 9, SeaMonkey và Safari. Thật không may trên Safari, nó không hoạt động kết hợp với sự kiện onf Focus).

Một ví dụ về việc sử dụng chức năng trên để buộc dấu bàn phím nhảy đến cuối tất cả các văn bản trên trang khi chúng nhận được tiêu điểm:

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)nghỉ khi selectStart bằng 0 như được chỉ ra bởi câu trả lời của jhnns.
mpartel

1
Điều này không làm việc cho tôi. Khi tôi nhấp vào hộp văn bản thực tế, tôi có vị trí dấu mũ sẽ bắt đầu. Kiểm tra fiddle của tôi jsfiddle.net/khx2w
elad.chen

Hàm setCaretP vị trí hoạt động tốt. Hàm addActionHandler của bạn, tuy nhiên, không. Nhưng ngay cả khi không có điều đó, tôi không thể khiến con trỏ di chuyển vào tiêu điểm. Rất có thể, đó là do trình duyệt tự đặt vị trí con trỏ dựa trên vị trí nhấp chuột. Dường như không có cách nào khác với những gì tôi có thể nói, nhưng tôi có thể hoàn toàn sai.
GJK

Hoạt động trong IE9, FF25, nhưng không phải Chrome 30. Tốt hơn là không có!
Umber Ferrule

Tôi có elem.value = elem.value.replace(/^9/g,'+79')mã. Trên con trỏ OperaMINI sau +. chức năng này không giúp được gì
eri

52

Liên kết trong câu trả lời bị hỏng, liên kết này sẽ hoạt động (tất cả các khoản tín dụng vào blog.vishalon.net ):

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

Trong trường hợp mã bị mất một lần nữa, đây là hai chức năng chính:

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 cho các chức năng cơ bản, mặc dù một số điều chỉnh phải được thực hiện . Số lượng dòng phải được trừ từ "pos", khi sử dụng phương thức phạm vi.
Rob W

36

Vì tôi thực sự cần giải pháp này và giải pháp cơ bản điển hình ( tập trung đầu vào - sau đó đặt giá trị bằng chính nó ) không hoạt động trên nhiều trình duyệt , tôi đã dành thời gian để chỉnh sửa và chỉnh sửa mọi thứ để nó hoạt động. Dựa trên mã của @ kd7 đây là những gì tôi nghĩ ra.

Thưởng thức! Hoạt động trong IE6 +, Firefox, Chrome, Safari, Opera

Kỹ thuật định vị dấu mũ trên trình duyệt chéo (ví dụ: di chuyển con trỏ đến END)

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

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

Thịt và khoai tây về cơ bản là setCaretPocation của @ kd7 , với sự điều chỉnh lớn nhất if (el.selectionStart || el.selectionStart === 0), trong firefox , selectStart bắt đầu từ 0 , trong đó boolean dĩ nhiên đang chuyển sang Sai, vì vậy nó đã bị phá vỡ ở đó.

Trong chrome, vấn đề lớn nhất là chỉ cung cấp cho nó .focus()là không đủ (nó cứ chọn TẤT CẢ văn bản!) Do đó, chúng tôi đặt giá trị của chính nó, el.value = el.value;trước khi gọi hàm của chúng tôi, và bây giờ nó đã nắm bắt & vị trí với đầu vào để sử dụng selectStart .

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 Tôi đang cố gắng sử dụng chức năng này khi một tiêu điểm được thực hiện trên một kiểu nhập văn bản, nhưng tôi không nhận được gì cả, bạn có thể giúp tôi áp dụng chức năng này bằng cách sử dụng javascript thuần túy không?
elad.chen

@ elad.chen Bạn đang cố gắng đặt chúng vào cuối hộp văn bản ngay khi chúng tập trung vào nó?
Mark Pieszak - Trilon.io

@mcpDESIGNS Tôi muốn đặt con trỏ vào đầu trường ngay khi phần tử đang được tập trung. Xem fiddle: jsfiddle.net/KuLTU/3
elad.chen

@ elad.chen Xin lỗi vì phản ứng muộn điên rồ! Chỉ cần thay đổi sự kiện đó thành .onclickthay vì .onfocustrong chức năng
search_field_f Focus

2
el.value = el.value; [...] if(el !== null)- Tôi sẽ trao đổi hai dòng này. Nếu ellà null, el.value = el.valuesẽ thất bại, vì vậy dòng đó sẽ nằm trong if.
BackSlash

21

Tôi đã điều chỉnh câu trả lời của kd7 một chút vì elem.selectionStart sẽ đánh giá thành sai khi selectStart là 0 ngẫu nhiên.

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

Tôi đã tìm thấy một cách dễ dàng để khắc phục sự cố này, đã được thử nghiệm trong IE và Chrome:

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

Truyền id hộp văn bản và vị trí dấu mũ cho chức năng này.


3

Nếu bạn cần tập trung một số hộp văn bản và vấn đề duy nhất của bạn là toàn bộ văn bản được tô sáng trong khi bạn muốn dấu mũ ở cuối, thì trong trường hợp cụ thể đó, bạn có thể sử dụng mẹo này để đặt giá trị hộp văn bản thành chính nó sau khi lấy nét:

$("#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 [object HTMLInputEuity] không có phương thức 'startedWith'
bobpaul

1
@bobpaul: tIDnên là id của phần tử, không phải chính đối tượng phần tử. Nếu bạn đang truyền đối tượng phần tử, bạn chỉ cần xóa 2 dòng đầu tiên trong phương thức này và nó sẽ hoạt động.
kinh ngạc

2

Tôi sẽ sửa các điều kiện như dưới đây:

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();
  }
 }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.