找出什么在真正的浏览器选择就是这么简单:是否有Internet Explorer批准的替代品selectionStart和selectionEnd?
var range = {
start: textbox.selectionStart,
end: textbox.selectionEnd
}
但IE,像往常一样,不明白。什么是最好的跨浏览器方式来做到这一点?
找出什么在真正的浏览器选择就是这么简单:是否有Internet Explorer批准的替代品selectionStart和selectionEnd?
var range = {
start: textbox.selectionStart,
end: textbox.selectionEnd
}
但IE,像往常一样,不明白。什么是最好的跨浏览器方式来做到这一点?
我会再次发布这个函数,看看这个问题是从另一个链接。
以下将在所有浏览器中完成这项工作,并处理所有新行问题而不会严重影响性能。我已经在some toing and froing之后到达此处,现在我相当确信这是最好的功能。
UPDATE
这个函数承担textarea的/输入具有焦点,所以你可能需要调用它之前调用的textarea的focus()
方法。
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
};
}
var el = document.getElementById("your_input");
el.focus();
var sel = getInputSelection(el);
alert(sel.start + ", " + sel.end);
我目前的解决方案是详细的,并基于this thread,但我打开更好的解决方案。
function getSelection(inputBox) {
if ("selectionStart" in inputBox) {
return {
start: inputBox.selectionStart,
end: inputBox.selectionEnd
}
}
//and now, the blinkered IE way
var bookmark = document.selection.createRange().getBookmark()
var selection = inputBox.createTextRange()
selection.moveToBookmark(bookmark)
var before = inputBox.createTextRange()
before.collapse(true)
before.setEndPoint("EndToStart", selection)
var beforeLength = before.text.length
var selLength = selection.text.length
return {
start: beforeLength,
end: beforeLength + selLength
}
}
这与新生产线的问题。请参阅@ bobince的回答关于此的一些背景,以及我对解决方案的回答。 – 2010-11-17 18:25:56
IE的范围实现是一个slithy恐怖。它确实希望您使用可执行的execCommand接口,而不是涉及索引到文本中的任何内容。
我知道有两种获取索引的方法,它们都有问题。第一个使用range.text和你的示例代码一样。不幸的是,range.text有一个习惯,即删除前导和尾随的换行符,这意味着如果脱字符/选择位于第一行以外的行的起始位置,beforeLength将会被(换行符数* 2)字符和您会得到错误的选定文本。
第二种方法是使用range.moveStart/End(在重复范围内),如以下问题的答案中所述:Character offset in an Internet Explorer TextRange(但是,因为您正在使用已知的textarea父级,可以忽略关于node-发现)。这并没有相同的问题,但它报告所有的索引,就好像换行符是简单的LF字符,即使textarea.value和range.text将它们作为CRLF序列返回!所以你不能直接使用它们来索引textarea,但是你可以用一堆换行符来修复它们,或者只是用字符串替换掉所有的值,然后再使用它。
function getCursorPosition($element) {
var position = 0,
selection;
if (document.selection) {
// IE Support
$element.focus();
selection = document.selection.createRange();
selection.moveStart ('character', -$element.value.length);
position = selection.text.length;
} else if ($element.selectionStart || $element.selectionStart === 0) {
position = $element.selectionStart;
}
return position;
}
function setCursorPosition($element, position) {
var selection;
if (document.selection) {
// IE Support
$element.focus();
selection = document.selection.createRange();
selection.moveStart ('character', -$element.value.length);
selection.moveStart ('character', position);
selection.moveEnd ('character', 0);
selection.select();
} else if ($element.selectionStart || $element.selectionStart === 0) {
$element.selectionStart = position;
$element.selectionEnd = position;
$element.focus();
}
}
我们是否可以根据某些非病毒许可证获得此许可,或者甚至可以为公有领域做出贡献? (这是那些关心版权的人的声音:-)) – 2010-12-10 22:37:06