<script>
var is_gecko = /gecko/i.test(navigator.userAgent);
var is_ie = /MSIE/.test(navigator.userAgent);
function insertNodeAtSelStart()
{
if(is_gecko)
{
var S = window.getSelection();
if(!S.isCollapsed)
{
var R = S.getRangeAt(0);
var R1 = R.cloneRange();
var NN = document.createElement("startMarker");
R1.insertNode(NN);
NN.parentNode.removeChild(NN);
}
}
if(is_ie)
{
// IE-specific code
}
}
</script>
<div>
<span>one two three</span>
</div>
<input type="button" value="Insert node at selection start" onclick="insertNodeAtSelStart();" />
首次在加载页面并选择一些文本后单击按钮,Firefox会清除选择。随后,它没有。这是我的代码或Firefox中的错误吗?
答案 0 :(得分:3)
Firefox通过成功将Node插入其起始点来清除选择。
对我来说,第二次单击有时(取决于选择的文本范围)会失败,并显示:
Error: uncaught exception: [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "..."]
在insertNode调用上。由于插入不成功,因此不会清除选择。大概这就是你正在发生的事情 - 检查你的错误控制台。
此失败似乎确实是Firefox错误。我无法完全找出触发它的确切条件,但它与选择中的节点边界有关。
我可以通过调用document.body.normalize()使整个span内容返回到单个Text节点,然后通过插入/删除循环进行分割,从而使您的示例始终工作(并清除选择)。 / p>
答案 1 :(得分:2)
事实上,你偶然发现了一个丑陋的Gecko虫子,这种虫子在多年的生命中不断爬行:( 是的,最新的开发版本仍然存在这个错误。
无论如何,如果您不想等待Mozilla的修复,更简单/更快的解决方法是在插入新节点之前折叠范围。
为了符合,这里是用于测试代码的(某种程度上简化的)样本:
<p id="para">select two or more letters, then </p>
<input id="butt" type="button" value="click me">
<script type="text/javascript">
if (!window.getSelection)
throw new Error("MSIE, you're not welcome!");
var marker = document.createElement('span');
marker.style.color = '#6C6';
marker.appendChild(document.createTextNode('|'));
function insertNodeAtSelStart() {
// window.getSelection().getRangeAt(0).insertNode(marker.cloneNode(true));
var r = window.getSelection().getRangeAt(0);
var n = marker.cloneNode(true);
r.collapse(true); // workaround for Gecko :(
r.insertNode(n); // Gecko sometimes(?!) fails with NS_ERROR_DOM_INDEX_SIZE_ERR
}
document.getElementById('butt').onclick = insertNodeAtSelStart;
</script>
OT,那不是“is _ gecko”,“is _ not _ ie”会更合适,因为这个代码应该在除MSIE之外的每个浏览器上按预期运行; - )