Dapatkan posisi kursor (dalam karakter) dalam bidang Input teks


212

Bagaimana saya bisa mendapatkan posisi tanda kuret dari dalam bidang input?

Saya telah menemukan beberapa bit dan potongan melalui Google, tetapi tidak ada bukti peluru.

Pada dasarnya sesuatu seperti plugin jQuery akan ideal, jadi saya bisa melakukannya

$("#myinput").caretPosition()

2
Coba cari 'posisi kursor', yang akan memberi Anda lebih banyak hits, serta beberapa topik tentang ini di SO.
Alec


2
@CMS Menemukan posisi dalam suatu <input>cara lebih sederhana daripada melakukannya dalam sebuah <textarea>.
Andrew Mao

1
@AndrewMao: dan jauh lebih sulit jika teksnya digulir dan tanda sisipan adalah sizekarakter masa lalu .
Dan Dascalescu

@ alec: Saya setuju mencari kursor dan bukannya caret dapat menghasilkan lebih banyak hasil. Seperti yang ditunjukkan di tempat lain, saya belajar bahwa caret adalah istilah yang lebih tepat. Sebuah kursor merupakan lokasi dalam apa pun sementara sisipan merupakan lokasi khusus dalam teks.
Suncat2000

Jawaban:


247

Pembaruan yang lebih mudah:

Gunakan field.selectionStart contoh dalam jawaban ini .

Terima kasih kepada @commonSenseCode untuk menunjukkan ini.


Jawaban lama:

Menemukan solusi ini. Tidak berbasis jquery tetapi tidak ada masalah untuk mengintegrasikannya ke 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')bisaelse if (typeof oField.selectionStart==='number')
user2428118

Apa gagasan "oField.focus ()"? Ini bekerja untuk saya tanpa garis ini. Hati-hati jika Anda menggunakan acara blur pada input Anda dan menjalankan fungsi itu di dalam panggilan balik.
Kirill Reznikov

Apakah Anda mengujinya di IE? Seluruh bagian itu dijalankan hanya pada IE. Di IE hanya ada seleksi global, itu sebabnya document.selection, bukan field.selectionatau sesuatu. Juga, dimungkinkan di IE 7 (tidak tahu apakah masih mungkin di 8+) untuk memilih sesuatu, dan kemudian TAB keluar dari lapangan tanpa kehilangan pilihan. Dengan cara ini, ketika teks dipilih tetapi bidang tidak fokus, document.selectionmengembalikan seleksi nol. Itu sebabnya, sebagai solusi untuk bug ini, Anda harus fokus pada elemen sebelum membaca document.selection.
bezmax

selalu mendapatkan 0 untuk chrome dan firefox
Kaushik Thanki

117

Bagus, terima kasih banyak untuk Max.

Saya telah memasukkan fungsionalitas dalam jawabannya menjadi jQuery jika ada yang ingin menggunakannya.

(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
Tidak input = $(this).get(0)sama dengan input = this?
Mic

4
@Mic tidak, tidak dalam plugin jQuery. Dalam sebuah plugin thismengacu pada set lengkap yang dibungkus. Namun kodenya masih salah, seharusnya begitu this.get(0). Kode-nya mungkin masih berfungsi karena membungkus ulang set yang dibungkus tidak menghasilkan apa-apa.
Chev

1
Ini memberi saya informasi yang salah. Saya melihat posisi kursor ketika membuka teks. Biola saya menunjukkan ini adalah: jsfiddle.net/fallenreaper/TSwyk
Fallenreaper

1
Firefox membuat NS_ERROR_FAILURE pada input.selectionStart ketika inputnya bertipe angka, bungkus dengan percobaan {} catch {}?
niall.campbell

akan menyenangkan untuk lebah baru jika Anda menambahkan penggunaan untuk fungsi
Muhammad Omer Aslam

100

SANGAT MUDAH

Jawaban yang diperbarui

Gunakan selectionStart, ini kompatibel dengan semua browser utama .

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

Pembaruan: Ini hanya berfungsi ketika tidak ada tipe yang didefinisikan atau type="text"pada input.


2
Jika saya mengubah posisi menggunakan mouse, itu tidak dicetak di konsol. Apakah ada cara untuk memperbaikinya?
Eugene Barsky

3
@EugeneBarsky Cukup tambahkan pendengar acara baru untuk acara klik. Anda dapat memeriksa .selectionStartproperti kapan saja ( document.getElementById('foobar').selectionStart), tidak harus berada di dalam pendengar acara.
JJJ

3
luar biasa, tetapi tidak berfungsi di Firefox atau Chrome saat jenis inputnya angka.
Adam R. Gray

26

Punya solusi yang sangat sederhana . Coba kode berikut dengan hasil yang diverifikasi -

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

Aku memberimu fiddle_demo


13
sliceadalah operasi yang relatif mahal dan tidak menambah apa pun pada 'solusi' ini - el.selectionStartsetara dengan panjang slice Anda; kembalikan saja itu. Selain itu, alasan solusi lain lebih rumit adalah karena mereka berurusan dengan browser lain yang tidak mendukung selectionStart.
mpen

Saya sudah berhenti dari pekerjaan di mana saya harus bekerja dengan kode dengan nama variabel seperti ini.
Michael Scheper

@ Michael Scheper - Maksud Anda 'el' untuk elemen dan 'val' untuk nilai? Itu sangat umum ...
user2782001

6
@ user2782001: Saya salah bicara — perhatian utama saya adalah nama fungsi. f1kira-kira bermakna seperti 'user2782001'. 😉
Michael Scheper

16

Sekarang ada plugin yang bagus untuk ini: Plugin Caret

Kemudian Anda bisa mendapatkan posisi menggunakan $("#myTextBox").caret()atau mengaturnya melalui$("#myTextBox").caret(position)


1
plugin caret tampaknya untuk elemen textarea bukan input
schmidlop

4
Yah saya membuatnya bekerja untuk <input type = "text" id = "myTextBox" /> dan menggunakan kode di atas.
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

Ada beberapa jawaban bagus yang diposting di sini, tetapi saya pikir Anda dapat menyederhanakan kode Anda dan melewatkan pemeriksaan untuk inputElement.selectionStartdukungan: itu tidak hanya didukung pada IE8 dan sebelumnya (lihat dokumentasi ) yang mewakili kurang dari 1% dari penggunaan browser saat ini .

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

Mungkin Anda memerlukan rentang yang dipilih selain posisi kursor. Ini adalah fungsi sederhana, Anda bahkan tidak perlu 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)');
    }
}

Katakanlah Anda ingin menyebutnya pada input setiap kali ia berubah atau mouse memindahkan posisi kursor (dalam hal ini kami menggunakan jQuery .on()). Untuk alasan kinerja, mungkin merupakan ide bagus untuk menambahkan setTimeout()atau sesuatu seperti Menggarisbawahi _debounce()jika ada acara:

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

Berikut adalah biola jika Anda ingin mencobanya: 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>

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.