javascript - 为什么 IE 在文本输入中的插入符号位置不等于字符串索引?解决方法是什么?

标签 javascript internet-explorer firefox google-chrome gecko

我并不感到惊讶,但我发现 IE8 在从文本中检索插入符位置方面的行为与 Chrome 和 Firefox 截然不同 <input><textarea> . Chrome 和 Firefox 将插入符位置报告为类似于字符串值中的索引,而 IE8 则不会。

首先,以下是我分别在 Chrome/Firefox 和 IE 中用来检索插入符号位置的函数:

function getCaretPosGecko(txtbox) {
    return txtbox.selectionStart;
}

function getCaretPosIE(txtbox) {
    var range, rangeCopy;    
    txtbox.focus();
    range = document.selection.createRange();    
    if (range !== null) {
        rangeCopy = range.duplicate();
        rangeCopy.moveToElementText(txtbox);
        rangeCopy.setEndPoint('EndToStart', range);    
        return rangeCopy.text.length - range.text.length;
    } else {
        return -1;
    }
}

据我所知,我实现的功能相当标准。现在,假设我有一个 <textarea> ,然后我在第一行键入一个“a”,在第二行键入一个“b”,仅此而已。上面的代码报告了 Chrome 和 Firefox 中给定条件的以下插入符号位置:

--------------------------------------------------------------------
| I put the caret...       | Code reports caret at position...     |
--------------------------------------------------------------------
| 1st line, after the "a"  | 1 (As expected)                       |
| 2nd line, before the "b" | 2 (As expected)                       |
| 2nd line, after the "b"  | 3 (As expected)                       |
--------------------------------------------------------------------

不幸的是,在 IE8 中,结果非常不同:

--------------------------------------------------------------------
| I put the caret...       | Code reports caret at position...     |
--------------------------------------------------------------------
| 1st line, after the "a"  | 1 (As expected)                       |
| 2nd line, before the "b" | 1 (Maybe it doesn't count new lines?) |
| 2nd line, after the "b"  | 4 (Now, it seems to include \r\n?)    |
--------------------------------------------------------------------

我假设 IE 在计算第三种情况时包含“\r\n”,但为什么它不包含第二种情况呢?

更重要的是,我可以做些什么来解决这个差异?我需要知道插入符号在文本框的字符串值中的位置才能进行一些字符串操作。我的第一个想法是将插入符在 IE 中的位置偏移插入符前“\r\n”的数量,但如果插入符位于一行的开头或结尾,这将不起作用。

这是一个工作示例:http://jsfiddle.net/FishBasketGordo/ExZM9/

编辑: @Tim Down 在下面的回答恰到好处。我确实需要做一些修改。下面的函数返回与其 Gecko 模拟完全相同的结果:

function getCaretPosIE(txtbox) {
    var caret, normalizedValue, range, textInputRange, len, endRange;    
    txtbox.focus();
    range = document.selection.createRange();    
    if (range && range.parentElement() == txtbox) {
        len = txtbox.value.length;
        normalizedValue = txtbox.value.replace(/\r\n/g, '');
        textInputRange = txtbox.createTextRange();
        textInputRange.moveToBookmark(range.getBookmark());
        endRange = txtbox.createTextRange();
        endRange.collapse(false);
        if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
            caret = txtbox.value.replace(/\r\n/g, '\n').length;
        } else {
            caret = -textInputRange.moveStart("character", -len);
            caret += normalizedValue.slice(0, start).split("\n").length - 1;
        }
    }
}

这是更正后的工作示例:http://jsfiddle.net/FishBasketGordo/uXWXF/

最佳答案

获取相对于文本区域的 value 属性的插入符号位置在 IE 中并不简单,因为您遇到过换行问题。我前段时间花了一些时间研究它并想出了我认为最好的方法。我已经在 Stack Overflow 上发布了几次。这是一个示例:

IE's document.selection.createRange doesn't include leading or trailing blank lines

关于javascript - 为什么 IE 在文本输入中的插入符号位置不等于字符串索引?解决方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6943000/

相关文章:

javascript - 循环中的 object.defineProperty

javascript - 在canvas html5中添加自定义动画

javascript - 如何使用 Raphael 和 jQuery 检测 IE 上的点击或鼠标按下

css - Firefox 在不透明度为 0 的 svg 中显示 tspan 文本(与所有其他现代浏览器不同)

css - Firefox:Div 元素上的背景图像过渡不起作用

javascript - Webkit 和 Firefox 之间的 "scrollWidth"行为不一致

javascript - D3JS - 组合 "rect"函数

javascript - TSLint。最大语句规则 - 可用吗?

c++ - 使用 C/C++ 自动化 Internet Explorer

css - IE 的规则。无法在 IE 10 中工作