Kullanıcının imleç konumunda bir metin alanına metin ekleyen basit bir işlev oluşturmak istiyorum. Temiz bir işlev olması gerekir. Sadece temel bilgiler. Gerisini çözebilirim.
Kullanıcının imleç konumunda bir metin alanına metin ekleyen basit bir işlev oluşturmak istiyorum. Temiz bir işlev olması gerekir. Sadece temel bilgiler. Gerisini çözebilirim.
Yanıtlar:
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;
Bu pasaj, birkaç satır jQuery 1.9+ ile size yardımcı olabilir: 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);
});
Doğru Javascript uğruna
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 = ...
. Onu korumanın bir yolu var mı?
https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setRangeText
Yine de bunun için tarayıcı desteğinden emin değilim.
Chrome 81'de test edilmiştir.
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>
Erik Pukinskis'in cevabının saf bir JS değişikliği:
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>
Chrome 47, 81 ve Firefox 76'da test edilmiştir.
Aynı alana yazarken o anda seçili metnin değerini değiştirmek isterseniz (otomatik tamamlama veya benzer bir efekt için), document.activeElement
ilk parametre olarak iletin.
Bunu yapmanın en zarif yolu bu değil ama oldukça basit.
Örnek kullanımlar:
typeInTextarea('hello');
typeInTextarea('haha', document.getElementById('some-id'));
Version 54.0.2813.0 canary (64-bit)
, temelde Chrome Canary 54.0.2813.0 olan kullanarak da çalışır . Son olarak, metin kutusuna kimliğe göre eklenmesini istiyorsanız , işlevin document.getElementById('insertyourIDhere')
yerine kullanın el
.
Erik Pukinskis
. Bunu daha iyi yansıtmak için cevabı güncelleyeceğim.
Firefox, chrome, opera, safari ve edge üzerinde çalışan ancak muhtemelen eski IE tarayıcılarda çalışmayacak basit bir çözüm.
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
işlevi mevcut seçimi sağlanan metinle değiştirmenize veya seçim yoksa imleç konumuna metni eklemenize izin verir. Bildiğim kadarıyla sadece firefox tarafından destekleniyor.
Diğer tarayıcılar için, yalnızca şu anda odaklanmış html öğesini etkileyen ve aynı davranışa sahip "insertText" komutu vardır. setRangeText
Bu makaleden kısmen esinlenildi
execCommand
desteklediği undo
ve yaptığı için tercih ediyorum . IE desteği yok ama daha küçük
execCommand
MDN tarafından eski kabul ediliyor: developer.mozilla.org/en-US/docs/Web/API/Document/execCommand Neden bilmiyorum, gerçekten yararlı görünüyor!
Rab'ın cevabı harika çalışıyor, ancak Microsoft Edge için değil, bu yüzden Edge için de küçük bir uyarlama ekledim:
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;
}
}
Basit javascript'i seviyorum ve genellikle etrafımda jQuery var. İşte mparkuk'lara dayanarak bulduğum şey :
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
})
İşte bir demo: 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>
Kullanıcı, metin eklendikten sonra girişe dokunmazsa, "giriş" olayı asla tetiklenmez ve değer özelliği değişikliği yansıtmaz. Bu nedenle, programlı olarak metin ekledikten sonra giriş olayını tetiklemek önemlidir. Alana odaklanmak yeterli değil.
Aşağıda Snorvarg'ın yanıtının bir kopyası ve sonunda bir giriş tetikleyicisi bulunmaktadır:
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);
}
}
TriggerEvent işlevi için plainjs.com'a kredi
Daha etkinlikte oninput yaklaşık olarak w3schools.com
Bunu bir sohbet için emoji seçici oluştururken keşfettim. Kullanıcı yalnızca birkaç emoji seçip "gönder" düğmesine basarsa, giriş alanına kullanıcı hiçbir zaman dokunmaz. Değer özniteliğini kontrol ederken, eklenen emoji unicodes giriş alanında görünmesine rağmen her zaman boştu. Kullanıcı alana dokunmazsa, "giriş" olayının asla tetiklenmediği ve çözümün onu bu şekilde tetiklediği ortaya çıktı. Bunu anlamak epey zaman aldı ... umarım birine biraz zaman kazandırır.
Kendi referansı için değiştirilmiş işlevi gönderme. Bu örnek, <select>
nesneden seçilen bir öğeyi ekler ve imleci etiketlerin arasına yerleştirir:
//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();
}
})
Aşağıdaki kod, Dmitriy Kubyshkin tarafından https://github.com/grassator/insert-text-at-cursor paketinin TypeScript uyarlamasıdır .
/**
* 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;
}
GetElementById (myField) olarak değiştirildi
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
yerel olarak depolamak performans için çok daha iyi
document.getElementById(myField)
! En üstte bir kez yapın ve bir değişken adı kullanın. Aynı öğeyi art arda kaç kez aramayı düşünüyorsunuz?