我想指定firefox选择一个范围。我可以使用range.select();轻松地使用IE。似乎FFX需要一个dom元素。我错了,还是有更好的方法来解决这个问题?
我首先获取文本选择,将其转换为范围(我认为?)并保存文本选择。这是我从最初获得范围的地方:
// Before modifying selection, save it
var userSelection,selectedText = '';
if(window.getSelection){
userSelection=window.getSelection();
}
else if(document.selection){
userSelection=document.selection.createRange();
}
selectedText=userSelection;
if(userSelection.text){
selectedText=userSelection.text;
}
if(/msie|MSIE/.test(navigator.userAgent) == false){
selectedText=selectedText.toString();
}
origRange = userSelection;
我稍后改变选择(成功)。我通过IE中的范围和ffx中的dom ID来实现。但是在我这样做之后,我想将选择设置回原始选择。
这就像IE中的魅力一样:
setTimeout(function(){
origRange.select();
},1000);
我想在FFX中做这样的事情:
var s = w.getSelection();
setTimeout(function(){
s.removeAllRanges();
s.addRange(origRange);
},1000);
不幸的是,FFX没有合作,这不起作用。有什么想法吗?
答案 0 :(得分:1)
简短的回答是:IE和其他浏览器在使用JavaScript选择文本的实现方面有所不同(IE有其专有方法)。看看Selecting text with JavaScript。
另请参阅MDC的setSelectionRange。
编辑:在做了一个小测试案例后,问题就变得清晰了。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>addRange test</title>
<style>
#trigger { background: lightgreen }
</style>
</head>
<body>
<p id="test">This is some (rather short) text.</p>
<span id="trigger">Trigger testCase().</span>
<script>
var origRange;
var reselectFunc = function () {
var savedRange = origRange;
savedRange.removeAllRanges();
savedRange.addRange(origRange);
};
var testCase = function () {
// Before modifying selection, save it
var userSelection,selectedText = '';
if(window.getSelection){
userSelection=window.getSelection();
}
else if(document.selection){
userSelection=document.selection.createRange();
}
selectedText=userSelection;
if(userSelection.text){
selectedText=userSelection.text;
}
if(/msie|MSIE/.test(navigator.userAgent) === false){
/* you shouldn't do this kind of browser sniffing,
users of Opera and WebKit based browsers
can easily spoof the UA string */
selectedText=selectedText.toString();
}
origRange = userSelection;
window.setTimeout(reselectFunc, 1000);
};
window.onload = function () {
var el = document.getElementById("trigger");
el.onmouseover = testCase;
};
</script>
</body>
</html>
在Firefox,Chromium和Opera中测试时,调试工具显示在removeAllRanges
中调用reselectFunc
后,savedRange
和origRange
都会重置。使用此类对象调用addRange
会导致在Firefox中抛出异常:
未被捕的例外:[例外...... “无法转换JavaScript参数 arg 0 [nsISelection.addRange]“ nsresult:“0x80570009 (NS_ERROR_XPC_BAD_CONVERT_JS)” 位置:“JS框架:: file:///home/mk/tests/addrange.html :: anonymous :: line 19“data:no]
无需说在所有三个浏览器中都没有选择文本。
显然这是预期的行为。调用removeAllRanges
后,所有分配了(DOM)Selection对象的变量都会重置。
答案 1 :(得分:0)
谢谢马塞尔。你是对的,诀窍是克隆范围,然后删除特定的原始范围。这样我们就可以恢复到克隆范围。你的帮助引导我到下面的代码,它将选择切换到其他地方,然后根据超时返回。
没有你我无法做到,并给你正确答案:D
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>addRange test</title>
<style>
#trigger { background: lightgreen }
</style>
</head>
<body>
<p id="switch">Switch to this text</p>
<p id="test">This is some (rather short) text.</p>
<span id="trigger">Trigger testCase().</span>
<script>
var origRange;
var s = window.getSelection();
var reselectFunc = function () {
s.removeAllRanges();
s.addRange(origRange);
};
var testCase = function () {
// Before modifying selection, save it
var userSelection,selectedText = '';
if(window.getSelection){
userSelection=window.getSelection();
}
else if(document.selection){
userSelection=document.selection.createRange();
}
selectedText=userSelection;
if(userSelection.text){
selectedText=userSelection.text;
}
if(/msie|MSIE/.test(navigator.userAgent) === false){
/* you shouldn't do this kind of browser sniffing,
users of Opera and WebKit based browsers
can easily spoof the UA string */
selectedText=selectedText.toString();
}
origRange = userSelection;
var range = s.getRangeAt(0);
origRange = range.cloneRange();
var sasDom = document.getElementById("switch");
s.removeRange(range);
range.selectNode(sasDom);
s.addRange(range);
window.setTimeout(reselectFunc, 1000);
};
window.onload = function () {
var el = document.getElementById("trigger");
el.onmouseover = testCase;
};
</script>
</body>
</html>