Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 更新textarea值,但保持光标位置_Javascript_Html - Fatal编程技术网

Javascript 更新textarea值,但保持光标位置

Javascript 更新textarea值,但保持光标位置,javascript,html,Javascript,Html,我有一个html文本区域,它将通过javascript定期更新 当我这样做时: $("#textarea").val(new_val); 光标移动到文本的末尾 我想在不改变光标位置的情况下更新文本。此外,如果用户选择了一系列文本,则应保留突出显示。以下是一对函数,用于获取和设置所有主要浏览器中文本区域中的选择/插入符号位置 注意:如果十年后您不需要支持IE,但这是我为替换文本区域中的项目而想到的。当替换为较长或较短的文本时,需要一些额外的处理来调整插入符号或选择 //在保留插入符号和选择的同

我有一个html文本区域,它将通过javascript定期更新

当我这样做时:

$("#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);