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()
MarkB29
sumber
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;
}
bezmax
sumber
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);
MarkB29
sumber
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.

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

Rajesh Paul
sumber
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)

Jens Mikkelsen
sumber
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);
George
sumber
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);
}
pmrotule
sumber
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/

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

Omar bakhsh
sumber