Rangy取代了父母

时间:2013-04-14 09:44:59

标签: javascript selection rangy

我已经尝试了很多方式来做这件事,而且下面是我最接近的。在chrome和IE8中完美运行(因为我尝试了许多其他版本),但是firefox坚决拒绝玩球。

test()函数应用于按钮,在选择页面上的某些粗体文本后单击该按钮。我想看到的是:

<b>blah</b> or <strong>blah</strong>

替换为

<span style='font-weight:bold'>blah</span>

在chrome和FF中它起作用,并且console.log行:

[WrappedRange("blah":0, "blah":4)] [object Text]
[WrappedRange("blah":0, "blah":4)] [object Text] 

但是在FF:

[WrappedRange("blah":0, "blah":4)] [object Text]
[WrappedRange(<SPAN>[1]:0, <SPAN>[1]:1)] [object HTMLSpanElement]

function test()
    {
    var sr=rangy.getSelection().getRangeAt(0);
    var oldParent=sameTextParent(sr);
    console.log(sr.inspect()+" "+sr.commonAncestorContainer);
    if(oldParent)
      {
      var newParent=document.createElement("span");
      newParent.style.fontWeight="bold";

      newParent.appendChild(sr.cloneContents());
      oldParent.parentNode.replaceChild(newParent,oldParent);

      rangy.getSelection().selectAllChildren(newParent);
      sr=rangy.getSelection().getRangeAt(0);
      console.log(sr.inspect()+" "+sr.commonAncestorContainer);
      }
    }
  function sameTextParent(r)
    {
    var s=r.startContainer,e=r.endContainer;
    if(s.nodeType!=3||e.nodeType!=3){console.log("not TEXT node!");return null}
    return (s.parentNode==e.parentNode)?s.parentNode:null;
    }

如果有人可以向我展示我的方式错误,以便它能够像在IE8和Chrome中那样在FF中工作,我会永远感激。

1 个答案:

答案 0 :(得分:3)

这是浏览器的不一致。在我看来,这并不坏,因为在任何一种情况下选择都是合理的,但它仍然是不一致的。最简单的解决方法是创建一个显式选择文本节点的范围,该节点在添加到所有主流浏览器中的选择后将保持不受影响。而不是

rangy.getSelection().selectAllChildren(newParent);

......我建议

var newRange = rangy.createRange();
newRange.setStart(newParent.firstChild, 0);
var lastChild = newParent.lastChild;
newRange.setEnd(lastChild,
    lastChild.nodeType == 3 ? lastChild.length : lastChild.childNodes.length);
rangy.getSelection().setSingleRange(newRange);

问题在于WebKit会在添加到选择中时对范围进行修改。您创建的范围在所有浏览器中都是相同的,但在添加到选择中时在某些浏览器中被更改,而不是Firefox。