Saya ingin membuat fungsi sederhana yang menambahkan teks ke dalam area teks pada posisi kursor pengguna. Itu harus menjadi fungsi yang bersih. Hanya dasar-dasarnya. Saya bisa mencari tahu sisanya.
Saya ingin membuat fungsi sederhana yang menambahkan teks ke dalam area teks pada posisi kursor pengguna. Itu harus menjadi fungsi yang bersih. Hanya dasar-dasarnya. Saya bisa mencari tahu sisanya.
Jawaban:
function insertAtCursor(myField, myValue) {
//IE support
if (document.selection) {
myField.focus();
sel = document.selection.createRange();
sel.text = myValue;
}
//MOZILLA and others
else if (myField.selectionStart || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)
+ myValue
+ myField.value.substring(endPos, myField.value.length);
} else {
myField.value += myValue;
}
}
} else {
myField.selectionStart = startPos + myValue.length;
myField.selectionEnd = startPos + myValue.length;
Cuplikan ini dapat membantu Anda dalam beberapa baris jQuery 1.9+: http://jsfiddle.net/4MBUG/2/
$('input[type=button]').on('click', function() {
var cursorPos = $('#text').prop('selectionStart');
var v = $('#text').val();
var textBefore = v.substring(0, cursorPos);
var textAfter = v.substring(cursorPos, v.length);
$('#text').val(textBefore + $(this).val() + textAfter);
});
Demi Javascript yang tepat
HTMLTextAreaElement.prototype.insertAtCaret = function (text) {
text = text || '';
if (document.selection) {
// IE
this.focus();
var sel = document.selection.createRange();
sel.text = text;
} else if (this.selectionStart || this.selectionStart === 0) {
// Others
var startPos = this.selectionStart;
var endPos = this.selectionEnd;
this.value = this.value.substring(0, startPos) +
text +
this.value.substring(endPos, this.value.length);
this.selectionStart = startPos + text.length;
this.selectionEnd = startPos + text.length;
} else {
this.value += text;
}
};
this.value = ...
. Apakah ada cara untuk melestarikannya?
https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setRangeText
Saya tidak yakin tentang dukungan browser untuk ini.
Diuji di Chrome 81.
function typeInTextarea(newText, el = document.activeElement) {
const [start, end] = [el.selectionStart, el.selectionEnd];
el.setRangeText(newText, start, end, 'select');
}
document.getElementById("input").onkeydown = e => {
if (e.key === "Enter") typeInTextarea("lol");
}
<input id="input" />
<br/><br/>
<div>Press Enter to insert "lol" at caret.</div>
<div>It'll replace a selection with the given text.</div>
Modifikasi JS murni dari jawaban Erik Pukinskis:
function typeInTextarea(newText, el = document.activeElement) {
const start = el.selectionStart
const end = el.selectionEnd
const text = el.value
const before = text.substring(0, start)
const after = text.substring(end, text.length)
el.value = (before + newText + after)
el.selectionStart = el.selectionEnd = start + newText.length
el.focus()
}
document.getElementById("input").onkeydown = e => {
if (e.key === "Enter") typeInTextarea("lol");
}
<input id="input" />
<br/><br/>
<div>Press Enter to insert "lol" at caret.</div>
Diuji di Chrome 47, 81, dan Firefox 76.
Jika Anda ingin mengubah nilai teks yang saat ini dipilih saat Anda mengetik di bidang yang sama (untuk pelengkapan otomatis atau efek serupa), teruskan document.activeElement
sebagai parameter pertama.
Ini bukan cara paling elegan untuk melakukan ini, tetapi cukup sederhana.
Contoh penggunaan:
typeInTextarea('hello');
typeInTextarea('haha', document.getElementById('some-id'));
Version 54.0.2813.0 canary (64-bit)
, yang pada dasarnya adalah Chrome Canary 54.0.2813.0. Akhirnya, jika Anda ingin memasukkannya ke dalam kotak teks berdasarkan ID, gunakan document.getElementById('insertyourIDhere')
di tempat el
fungsi.
Erik Pukinskis
. Saya akan memperbarui jawaban untuk lebih mencerminkan itu.
Solusi sederhana yang berfungsi di firefox, chrome, opera, safari, dan edge, tetapi mungkin tidak berfungsi di browser IE lama.
var target = document.getElementById("mytextarea_id")
if (target.setRangeText) {
//if setRangeText function is supported by current browser
target.setRangeText(data)
} else {
target.focus()
document.execCommand('insertText', false /*no UI*/, data);
}
}
setRangeText
fungsi memungkinkan Anda untuk mengganti pilihan saat ini dengan teks yang disediakan atau jika tidak ada pilihan maka masukkan teks pada posisi kursor. Ini hanya didukung oleh firefox sejauh yang saya tahu.
Untuk browser lain ada perintah "insertText" yang hanya mempengaruhi elemen html yang saat ini difokuskan dan memiliki perilaku yang sama seperti setRangeText
Terinspirasi sebagian oleh artikel ini
execCommand
karena mendukung undo
dan membuat insert-text-textarea . Tidak ada dukungan IE tetapi lebih kecil
execCommand
dianggap usang oleh MDN: developer.mozilla.org/en-US/docs/Web/API/Document/execCommand Saya tidak tahu mengapa, ini tampaknya sangat berguna!
Jawaban Rab berfungsi dengan baik, tetapi tidak untuk Microsoft Edge, jadi saya menambahkan adaptasi kecil untuk Edge juga:
https://jsfiddle.net/et9borp4/
function insertAtCursor(myField, myValue) {
//IE support
if (document.selection) {
myField.focus();
sel = document.selection.createRange();
sel.text = myValue;
}
// Microsoft Edge
else if(window.navigator.userAgent.indexOf("Edge") > -1) {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)+ myValue
+ myField.value.substring(endPos, myField.value.length);
var pos = startPos + myValue.length;
myField.focus();
myField.setSelectionRange(pos, pos);
}
//MOZILLA and others
else if (myField.selectionStart || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)
+ myValue
+ myField.value.substring(endPos, myField.value.length);
} else {
myField.value += myValue;
}
}
Saya suka javascript sederhana, dan saya biasanya memiliki jQuery. Inilah yang saya dapatkan, berdasarkan mparkuk :
function typeInTextarea(el, newText) {
var start = el.prop("selectionStart")
var end = el.prop("selectionEnd")
var text = el.val()
var before = text.substring(0, start)
var after = text.substring(end, text.length)
el.val(before + newText + after)
el[0].selectionStart = el[0].selectionEnd = start + newText.length
el.focus()
}
$("button").on("click", function() {
typeInTextarea($("textarea"), "some text")
return false
})
Berikut demonya: http://codepen.io/erikpukinskis/pen/EjaaMY?editors=101
function insertAtCaret(text) {
const textarea = document.querySelector('textarea')
textarea.setRangeText(
text,
textarea.selectionStart,
textarea.selectionEnd,
'end'
)
}
setInterval(() => insertAtCaret('Hello'), 3000)
<textarea cols="60">Stack Overflow Stack Exchange Starbucks Coffee</textarea>
Jika pengguna tidak menyentuh input setelah teks dimasukkan, peristiwa 'input' tidak pernah dipicu, dan atribut nilai tidak akan mencerminkan perubahan. Oleh karena itu, penting untuk memicu peristiwa masukan setelah memasukkan teks secara terprogram. Memfokuskan pada bidang saja tidak cukup.
Berikut ini adalah salinan jawaban Snorvarg dengan pemicu masukan di akhir:
function insertAtCursor(myField, myValue) {
//IE support
if (document.selection) {
myField.focus();
sel = document.selection.createRange();
sel.text = myValue;
}
// Microsoft Edge
else if(window.navigator.userAgent.indexOf("Edge") > -1) {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)+ myValue
+ myField.value.substring(endPos, myField.value.length);
var pos = startPos + myValue.length;
myField.focus();
myField.setSelectionRange(pos, pos);
}
//MOZILLA and others
else if (myField.selectionStart || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)
+ myValue
+ myField.value.substring(endPos, myField.value.length);
} else {
myField.value += myValue;
}
triggerEvent(myField,'input');
}
function triggerEvent(el, type){
if ('createEvent' in document) {
// modern browsers, IE9+
var e = document.createEvent('HTMLEvents');
e.initEvent(type, false, true);
el.dispatchEvent(e);
} else {
// IE 8
var e = document.createEventObject();
e.eventType = type;
el.fireEvent('on'+e.eventType, e);
}
}
Kredit ke plainjs.com untuk fungsi triggerEvent
Selengkapnya tentang acara oninput di w3schools.com
Saya menemukan ini saat membuat pemetik emoji untuk obrolan. Jika pengguna hanya memilih beberapa emoji dan menekan tombol "kirim", bidang input tidak akan pernah disentuh oleh pengguna. Saat memeriksa atribut value, kolom tersebut selalu kosong, meskipun unicode emoji yang dimasukkan terlihat di kolom input. Ternyata jika pengguna tidak menyentuh bidang, peristiwa 'input' tidak pernah diaktifkan dan solusinya adalah memicunya seperti ini. Butuh waktu cukup lama untuk memikirkan yang satu ini ... semoga bisa menghemat waktu.
Memposting fungsi yang dimodifikasi untuk referensi sendiri. Contoh ini menyisipkan item yang dipilih dari <select>
objek dan meletakkan tanda sisipan di antara tag:
//Inserts a choicebox selected element into target by id
function insertTag(choicebox,id) {
var ta=document.getElementById(id)
ta.focus()
var ss=ta.selectionStart
var se=ta.selectionEnd
ta.value=ta.value.substring(0,ss)+'<'+choicebox.value+'>'+'</'+choicebox.value+'>'+ta.value.substring(se,ta.value.length)
ta.setSelectionRange(ss+choicebox.value.length+2,ss+choicebox.value.length+2)
}
/**
* Usage "foo baz".insertInside(4, 0, "bar ") ==> "foo bar baz"
*/
String.prototype.insertInside = function(start, delCount, newSubStr) {
return this.slice(0, start) + newSubStr + this.slice(start + Math.abs(delCount));
};
$('textarea').bind("keydown keypress", function (event) {
var val = $(this).val();
var indexOf = $(this).prop('selectionStart');
if(event.which === 13) {
val = val.insertInside(indexOf, 0, "<br>\n");
$(this).val(val);
$(this).focus();
}
})
Kode di bawah ini adalah adaptasi TypeScript dari paket https://github.com/grassator/insert-text-at-cursor oleh Dmitriy Kubyshkin.
/**
* Inserts the given text at the cursor. If the element contains a selection, the selection
* will be replaced by the text.
*/
export function insertText(input: HTMLTextAreaElement | HTMLInputElement, text: string) {
// Most of the used APIs only work with the field selected
input.focus();
// IE 8-10
if ((document as any).selection) {
const ieRange = (document as any).selection.createRange();
ieRange.text = text;
// Move cursor after the inserted text
ieRange.collapse(false /* to the end */);
ieRange.select();
return;
}
// Webkit + Edge
const isSuccess = document.execCommand("insertText", false, text);
if (!isSuccess) {
const start = input.selectionStart;
const end = input.selectionEnd;
// Firefox (non-standard method)
if (typeof (input as any).setRangeText === "function") {
(input as any).setRangeText(text);
} else {
if (canManipulateViaTextNodes(input)) {
const textNode = document.createTextNode(text);
let node = input.firstChild;
// If textarea is empty, just insert the text
if (!node) {
input.appendChild(textNode);
} else {
// Otherwise we need to find a nodes for start and end
let offset = 0;
let startNode = null;
let endNode = null;
// To make a change we just need a Range, not a Selection
const range = document.createRange();
while (node && (startNode === null || endNode === null)) {
const nodeLength = node.nodeValue.length;
// if start of the selection falls into current node
if (start >= offset && start <= offset + nodeLength) {
range.setStart((startNode = node), start - offset);
}
// if end of the selection falls into current node
if (end >= offset && end <= offset + nodeLength) {
range.setEnd((endNode = node), end - offset);
}
offset += nodeLength;
node = node.nextSibling;
}
// If there is some text selected, remove it as we should replace it
if (start !== end) {
range.deleteContents();
}
// Finally insert a new node. The browser will automatically
// split start and end nodes into two if necessary
range.insertNode(textNode);
}
} else {
// For the text input the only way is to replace the whole value :(
const value = input.value;
input.value = value.slice(0, start) + text + value.slice(end);
}
}
// Correct the cursor position to be at the end of the insertion
input.setSelectionRange(start + text.length, start + text.length);
// Notify any possible listeners of the change
const e = document.createEvent("UIEvent");
e.initEvent("input", true, false);
input.dispatchEvent(e);
}
}
function canManipulateViaTextNodes(input: HTMLTextAreaElement | HTMLInputElement) {
if (input.nodeName !== "TEXTAREA") {
return false;
}
let browserSupportsTextareaTextNodes;
if (typeof browserSupportsTextareaTextNodes === "undefined") {
const textarea = document.createElement("textarea");
textarea.value = "1";
browserSupportsTextareaTextNodes = !!textarea.firstChild;
}
return browserSupportsTextareaTextNodes;
}
Mengubahnya menjadi getElementById (myField)
function insertAtCursor(myField, myValue) {
//IE support
if (document.selection) {
document.getElementById(myField).focus();
sel = document.selection.createRange();
sel.text = myValue;
}
//MOZILLA and others
else if (document.getElementById(myField).selectionStart || document.getElementById(myField).selectionStart == '0') {
var startPos = document.getElementById(myField).selectionStart;
var endPos = document.getElementById(myField).selectionEnd;
document.getElementById(myField).value = document.getElementById(myField).value.substring(0, startPos)
+ myValue
+ document.getElementById(myField).value.substring(endPos, document.getElementById(myField).value.length);
} else {
document.getElementById(myField).value += myValue;
}
}
myfield
sebagai lokal jauh lebih baik untuk kinerja
document.getElementById(myField)
! Lakukan sekali di atas dan gunakan nama variabel. Berapa kali berturut-turut Anda berniat mencari elemen yang sama secara berulang?