Javascript 更新textarea值,但保持光标位置
我有一个html文本区域,它将通过javascript定期更新 当我这样做时:Javascript 更新textarea值,但保持光标位置,javascript,html,Javascript,Html,我有一个html文本区域,它将通过javascript定期更新 当我这样做时: $("#textarea").val(new_val); 光标移动到文本的末尾 我想在不改变光标位置的情况下更新文本。此外,如果用户选择了一系列文本,则应保留突出显示。以下是一对函数,用于获取和设置所有主要浏览器中文本区域中的选择/插入符号位置 注意:如果十年后您不需要支持IE,但这是我为替换文本区域中的项目而想到的。当替换为较长或较短的文本时,需要一些额外的处理来调整插入符号或选择 //在保留插入符号和选择的同
$("#textarea").val(new_val);
光标移动到文本的末尾
我想在不改变光标位置的情况下更新文本。此外,如果用户选择了一系列文本,则应保留突出显示。以下是一对函数,用于获取和设置所有主要浏览器中文本区域中的选择/插入符号位置
注意:如果十年后您不需要支持IE,但这是我为替换文本区域中的项目而想到的。当替换为较长或较短的文本时,需要一些额外的处理来调整插入符号或选择
//在保留插入符号和选择的同时在textarea中查找和替换
函数replaceText(el、findText、replaceText){
var text=el.value;
var selectionStart=0;
var-selectionEnd=0;
//仅支持保留插入符号和选择的现代浏览器
如果(标高设置选择范围){
selectionStart=el.selectionStart;
selectionEnd=el.selectionEnd;
}
var start=0;
而((start=text.indexOf(findText,start))>-1){
var end=start+findText.length;
text=text.substr(0,开始)+replaceWithText+text.substr(结束);
如果(选择开始<结束){
selectionStart=Math.min(selectionStart,start+replaceWithText.length);
}否则{
selectionStart=selectionStart+replaceWithText.length-(结束-开始);
}
如果(选择结束<结束){
selectionEnd=Math.min(selectionEnd,start+replaceWithText.length);
}否则{
selectionEnd=selectionEnd+replaceWithText.length-(结束-开始);
}
开始+=替换为text.length;
}
//除非我们需要,否则不要做任何事情(否则会破坏撤销)
如果(el.value!=文本){
el.value=文本;
如果(标高设置选择范围){
el.selectionStart=selectionStart;
el.selectionEnd=selectionEnd;
}
}
}
将插入符号放在单词上或后面,或在单词后面或后面选择一些文本:
这是
一些较长的文字
取代
设置输入选择功能是否仅在IE中工作?我这样问是因为其他浏览器中不存在createTextRange
方法(用于输入元素),因此引发了一个错误。我使用您的代码创建了一个演示。代码在这里:演示在这里:演示在IE9测试版、Chrome和Safari中完美运行。但是,在Firefox中有一个问题:如果你用编程方式设置了选择(<代码> Sale.SET(输入,10, 20); >,除非你聚焦文本框(<代码>输入.FooSUME);),否则它不能正常工作。在我的演示中,在设置选择后,我正在聚焦文本框,只是为了使它在Firefox中工作。因此,考虑放置<代码> EL。在setInputSelection
函数的末尾。这仍然是处理这一问题的最佳方法吗?我在一个较老的项目中遇到了这段代码,对于这样一个看似简单的问题来说,这段代码似乎很长/复杂task@Marie:对于IE来说,复杂的是一个注释-typeof NaN==“number”
变成了true
.T他恰好没有碰到那个边界问题,但万一有人把代码弄乱了,他们应该知道处理那个问题会更有效。
function getInputSelection(el) {
var start = 0, end = 0, normalizedValue, range,
textInputRange, len, endRange;
if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
start = el.selectionStart;
end = el.selectionEnd;
} else {
range = document.selection.createRange();
if (range && range.parentElement() == el) {
len = el.value.length;
normalizedValue = el.value.replace(/\r\n/g, "\n");
// Create a working TextRange that lives only in the input
textInputRange = el.createTextRange();
textInputRange.moveToBookmark(range.getBookmark());
// Check if the start and end of the selection are at the very end
// of the input, since moveStart/moveEnd doesn't return what we want
// in those cases
endRange = el.createTextRange();
endRange.collapse(false);
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
start = end = len;
} else {
start = -textInputRange.moveStart("character", -len);
start += normalizedValue.slice(0, start).split("\n").length - 1;
if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
end = len;
} else {
end = -textInputRange.moveEnd("character", -len);
end += normalizedValue.slice(0, end).split("\n").length - 1;
}
}
}
}
return {
start: start,
end: end
};
}
function offsetToRangeCharacterMove(el, offset) {
return offset - (el.value.slice(0, offset).split("\r\n").length - 1);
}
function setInputSelection(el, startOffset, endOffset) {
if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
el.selectionStart = startOffset;
el.selectionEnd = endOffset;
} else {
var range = el.createTextRange();
var startCharMove = offsetToRangeCharacterMove(el, startOffset);
range.collapse(true);
if (startOffset == endOffset) {
range.move("character", startCharMove);
} else {
range.moveEnd("character", offsetToRangeCharacterMove(el, endOffset));
range.moveStart("character", startCharMove);
}
range.select();
}
}
var t = document.getElementById("textarea");
var sel = getInputSelection(t);
t.value = some_new_value;
setInputSelection(t, sel.start, sel.end);