Nhận vị trí con trỏ (tính bằng ký tự) trong trường Nhập văn bản


211

Làm cách nào tôi có thể có được vị trí dấu mũ từ trong trường nhập?

Tôi đã tìm thấy một vài bit và mảnh thông qua Google, nhưng không có bằng chứng đạn.

Về cơ bản một cái gì đó như một plugin jQuery sẽ là lý tưởng, vì vậy tôi chỉ có thể làm

$("#myinput").caretPosition()

2
Hãy thử tìm kiếm 'vị trí con trỏ', điều đó sẽ mang lại cho bạn nhiều lượt truy cập hơn, cũng như một số chủ đề về điều này trên SO.
Alec


2
@CMS Tìm vị trí trong một <input>cách đơn giản hơn so với thực hiện nó trong một <textarea>.
Andrew Mao

1
@AndrewMao: và khó hơn nếu văn bản được cuộn và dấu mũ là các sizeký tự trong quá khứ .
Dan Dascalescu

@alec: Tôi đồng ý tìm kiếm con trỏ thay vì dấu mũ có thể mang lại kết quả cao hơn. Như đã chỉ ra ở nơi khác, tôi đã học được rằng caret là thuật ngữ thích hợp hơn. Một con trỏ biểu thị một vị trí trong bất cứ thứ gì trong khi dấu mũ biểu thị một vị trí cụ thể trong văn bản.
Suncat2000

Câu trả lời:


247

Cập nhật dễ dàng hơn:

Sử dụng field.selectionStart ví dụ trong câu trả lời này .

Cảm ơn @commonSenseCode đã chỉ ra điều này.


Câu trả lời cũ:

Tìm thấy giải pháp này. Không dựa trên jquery nhưng không có vấn đề gì để tích hợp nó vào jquery:

/*
** Returns the caret (cursor) position of the specified text field (oField).
** Return value range is 0-oField.value.length.
*/
function doGetCaretPosition (oField) {

  // Initialize
  var iCaretPos = 0;

  // IE Support
  if (document.selection) {

    // Set focus on the element
    oField.focus();

    // To get cursor position, get empty selection range
    var oSel = document.selection.createRange();

    // Move selection start to 0 position
    oSel.moveStart('character', -oField.value.length);

    // The caret position is selection length
    iCaretPos = oSel.text.length;
  }

  // Firefox support
  else if (oField.selectionStart || oField.selectionStart == '0')
    iCaretPos = oField.selectionDirection=='backward' ? oField.selectionStart : oField.selectionEnd;

  // Return results
  return iCaretPos;
}

9
else if (oField.selectionStart || oField.selectionStart == '0')có thể làelse if (typeof oField.selectionStart==='number')
user2428118

Ý tưởng của "oField.f Focus ()" là gì? Nó hoạt động cho tôi mà không có dòng này. Hãy cẩn thận nếu bạn sử dụng sự kiện mờ trên đầu vào của bạn và thực hiện chức năng đó trong một cuộc gọi lại.
Kirill Reznikov

Bạn đang thử nghiệm điều đó trên IE? Đó là toàn bộ nếu phần chỉ được thực hiện trên IE. Trong IE chỉ có một lựa chọn toàn cầu, đó là lý do tại sao nó document.selection, không phải field.selectionhoặc một cái gì đó. Ngoài ra, trong IE 7 (không thể biết trong 8+) vẫn có thể chọn thứ gì đó, và sau đó TAB ra khỏi trường mà không mất lựa chọn. Bằng cách này, khi văn bản được chọn nhưng trường không được tập trung, document.selectiontrả về lựa chọn bằng không. Đó là lý do tại sao, như một cách giải quyết cho lỗi này, bạn phải tập trung vào phần tử trước khi đọc document.selection.
bezmax

luôn nhận được 0 cho chrome và firefox
Kaushik Thanki

117

Đẹp một, cảm ơn Max.

Tôi đã gói chức năng trong câu trả lời của anh ấy vào jQuery nếu có ai muốn sử dụng nó.

(function($) {
    $.fn.getCursorPosition = function() {
        var input = this.get(0);
        if (!input) return; // No (input) element found
        if ('selectionStart' in input) {
            // Standard-compliant browsers
            return input.selectionStart;
        } else if (document.selection) {
            // IE
            input.focus();
            var sel = document.selection.createRange();
            var selLen = document.selection.createRange().text.length;
            sel.moveStart('character', -input.value.length);
            return sel.text.length - selLen;
        }
    }
})(jQuery);

3
Không input = $(this).get(0)giống như input = this?
Mic

4
@Mic không, không phải trong một plugin jQuery. Trong một plugin thisđề cập đến một bộ bọc đầy đủ. Mã của anh ấy vẫn sai, mặc dù vậy this.get(0). Mã của anh ta có thể vẫn hoạt động vì bọc lại một bộ bọc không làm gì cả.
Chev

1
Điều này cho tôi thông tin sai. Tôi đã nhìn vào vị trí con trỏ khi nhập văn bản. Fiddle
Fallenreaper

1
Firefox tạo NS_ERROR_FAILURE trên input.selectionStart khi đầu vào có kiểu số, bọc nó trong một thử {} bắt {}?
niall.campbell

sẽ tốt cho những con ong mới nếu bạn thêm cách sử dụng chức năng
Muhammad Omer Aslam

98

RẤT DỄ

Cập nhật câu trả lời

Sử dụng selectionStart, nó tương thích với tất cả các trình duyệt chính .

document.getElementById('foobar').addEventListener('keyup', e => {
  console.log('Caret at: ', e.target.selectionStart)
})
<input id="foobar" />

Cập nhật: Điều này chỉ hoạt động khi không có loại được xác định hoặc type="text"trên đầu vào.


2
Nếu tôi thay đổi vị trí bằng chuột, nó sẽ không được in trong bảng điều khiển. Có cách nào để khắc phục nó?
Eugene Barsky

3
@EugeneBarsky Chỉ cần thêm một trình nghe sự kiện mới cho sự kiện nhấp chuột. Bạn có thể kiểm tra .selectionStarttài sản bất cứ lúc nào ( document.getElementById('foobar').selectionStart), nó không phải ở trong một trình lắng nghe sự kiện.
JJJ

3
tuyệt vời, nhưng không hoạt động trong Firefox hoặc Chrome khi loại đầu vào là số.
Adam R. Gray

26

Có một giải pháp rất đơn giản . Hãy thử mã sau đây với kết quả được xác minh -

<html>
<head>
<script>
    function f1(el) {
    var val = el.value;
    alert(val.slice(0, el.selectionStart).length);
}
</script>
</head>
<body>
<input type=text id=t1 value=abcd>
    <button onclick="f1(document.getElementById('t1'))">check position</button>
</body>
</html>

Tôi đang đưa cho bạn fiddle_demo


13
slicelà một hoạt động tương đối tốn kém và nó không thêm gì vào 'giải pháp' này - el.selectionStarttương đương với độ dài của lát cắt của bạn; chỉ cần trả lại Hơn nữa, lý do các giải pháp khác phức tạp hơn là vì chúng xử lý các trình duyệt khác không hỗ trợ selectionStart.
mở

Tôi đã bỏ công việc mà tôi phải làm việc với mã có tên biến như thế này.
Michael Scheper

@Michael Scheper - Ý bạn là 'el' cho phần tử và 'val' cho giá trị? Chúng khá phổ biến ...
user2782001

6
@ user2782001: Tôi nhớ chính tả mối quan tâm chính của tôi là tên hàm. f1có ý nghĩa như 'user2782001'. 😉
Michael Scheper

16

Hiện tại có một plugin tốt cho việc này: Plugin Caret

Sau đó, bạn có thể nhận vị trí bằng cách sử dụng $("#myTextBox").caret()hoặc đặt nó qua$("#myTextBox").caret(position)


1
plugin caret dường như dành cho các yếu tố textarea không phải đầu vào
schmidlop

4
Vâng, tôi đã làm cho nó hoạt động cho <input type = "text" id = "myTextBox" /> và sử dụng mã ở trên.
Jens Mikkelsen

14
   (function($) {
    $.fn.getCursorPosition = function() {
        var input = this.get(0);
        if (!input) return; // No (input) element found
        if (document.selection) {
            // IE
           input.focus();
        }
        return 'selectionStart' in input ? input.selectionStart:'' || Math.abs(document.selection.createRange().moveStart('character', -input.value.length));
     }
   })(jQuery);

10

Có một vài câu trả lời hay được đăng ở đây, nhưng tôi nghĩ bạn có thể đơn giản hóa mã của mình và bỏ qua kiểm tra để được inputElement.selectionStarthỗ trợ: nó không chỉ được hỗ trợ trên IE8 trở về trước (xem tài liệu ) đại diện cho ít hơn 1% mức sử dụng trình duyệt hiện tại .

var input = document.getElementById('myinput'); // or $('#myinput')[0]
var caretPos = input.selectionStart;

// and if you want to know if there is a selection or not inside your input:

if (input.selectionStart != input.selectionEnd)
{
    var selectionValue =
    input.value.substring(input.selectionStart, input.selectionEnd);
}

2

Có lẽ bạn cần một phạm vi được chọn ngoài vị trí con trỏ. Đây là một hàm đơn giản, thậm chí bạn không cần jQuery:

function caretPosition(input) {
    var start = input[0].selectionStart,
        end = input[0].selectionEnd,
        diff = end - start;

    if (start >= 0 && start == end) {
        // do cursor position actions, example:
        console.log('Cursor Position: ' + start);
    } else if (start >= 0) {
        // do ranged select actions, example:
        console.log('Cursor Position: ' + start + ' to ' + end + ' (' + diff + ' selected chars)');
    }
}

Giả sử bạn muốn gọi nó trên đầu vào bất cứ khi nào nó thay đổi hoặc chuột di chuyển vị trí con trỏ (trong trường hợp này chúng tôi đang sử dụng jQuery .on()). Vì lý do hiệu suất, có thể là một ý tưởng tốt để thêm setTimeout()hoặc một cái gì đó như Underscores _debounce()nếu các sự kiện được đưa vào:

$('input[type="text"]').on('keyup mouseup mouseleave', function() {
    caretPosition($(this));
});

Đây là một câu đố nếu bạn muốn dùng thử: https://jsfiddle.net/Dhaupin/91189tq7/


0

const inpT = document.getElementById("text-box");
const inpC = document.getElementById("text-box-content");
// swch gets  inputs .
var swch;
// swch  if corsur is active in inputs defaulte is false .
var isSelect = false;

var crnselect;
// on focus
function setSwitch(e) {
  swch = e;
  isSelect = true;
  console.log("set Switch: " + isSelect);
}
// on click ev
function setEmoji() {
  if (isSelect) {
    console.log("emoji added :)");
    swch.value += ":)";
    swch.setSelectionRange(2,2 );
    isSelect = true;
  }

}
// on not selected on input . 
function onout() {
  // الافنت  اون كي اب 
  crnselect = inpC.selectionStart;
  
  // return input select not active after 200 ms .
  var len = swch.value.length;
  setTimeout(() => {
   (len == swch.value.length)? isSelect = false:isSelect = true;
  }, 200);
}
<h1> Try it !</h1>
    
		<input type="text" onfocus = "setSwitch(this)" onfocusout = "onout()" id="text-box" size="20" value="title">
		<input type="text" onfocus = "setSwitch(this)"  onfocusout = "onout()"  id="text-box-content" size="20" value="content">
<button onclick="setEmoji()">emogi :) </button>

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.