为什么IE's插入符在文本输入中的位置不等于字符串索引?解决方法是什么?
Why doesn't IE's caret position in a text input equal the string index? What's the workaround?
我并不感到惊讶,但我发现IE8在从文本<input>
或<textarea>
检索插入符号位置方面的行为与Chrome和Firefox非常不同。虽然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",但为什么不包括它的第二种情况?
更重要的是,我可以做些什么来解决这个差异?我需要知道插入符号在文本框的字符串值内做一些字符串操作。我的第一个想法是在插入符号之前通过"'r'n"的数量来抵消插入符号在IE中的位置,但如果插入符号位于一行的开头或结尾,这将不起作用。
下面是一个工作示例: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不包括前后空行
- CORS:访问控制允许原点不等于提供的原点
- 谷歌地图 - 用户选择不允许位置
- 为什么我的 React getDOMNode().textContent JavaScript 字符串不等于字符串
- 在JavaScript中,是否存在空字符串不等于空字符串的情况
- 数组长度不等于数组对象
- XMLHttpRequest内容长度不等于文件的实际大小
- 正则表达式 - 值不等于 0,00
- 如何从MongoDB中选择所有文档,其中一个字段不等于某个值
- 原型遗传:为什么假不等于假
- DIV 的 HTML 长度不等于 AJAX 加载的 HTML 长度
- 如果当前网址不包含位置搜索,请重定向到主页
- 如何在一个索引不等于2的ul中获取li,我知道如何获得索引gt或lt 2
- 如何使用 javascript 检查两个值是否不等于空
- 为什么 +true 不等于 true.valueOf
- 解析的 JSON 不等于原始数据
- Jquery或Javascript计算两个字段中的字符数,如果不等于20
- _对象的.depClone,不等于旧对象
- 如果一个字符串没有'It’不等于一堆东西
- 检查value是否不等于数组中的位置
- 为什么IE's插入符在文本输入中的位置不等于字符串索引?解决方法是什么?