1

我想指定firefox选择一个范围。我可以使用 IE 轻松做到这一点,使用 range.select();。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 没有合作,这不起作用。有任何想法吗?

4

2 回答 2

1

简短的回答是:IE 和其他浏览器在使用 JavaScript 选择文本的实现上有所不同(IE 有其专有的方法)。看看使用 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 中对此进行测试时,调试工具显示在调用removeAllRangesin后reselectFunc,两者都savedRangeorigRange重置。使用这样的对象调用addRange会导致 Firefox 中抛出异常:

未捕获的异常:[异常...“无法转换 JavaScript 参数 arg 0 [nsISelection.addRange]”nsresult:“0x80570009 (NS_ERROR_XPC_BAD_CONVERT_JS)”位置:“JS 框架 :: file:///home/mk/tests/addrange。 html :: 匿名 :: 第 19 行”数据:无]

不用说在所有三个浏览器中都没有选择文本。

显然这是预期的行为。分配了 (DOM)Selection 对象的所有变量在调用removeAllRanges.

于 2010-04-19T23:37:15.913 回答
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>
于 2010-04-20T04:48:22.057 回答