使用javascript扩展DOM范围以覆盖部分选定的节点

ko-*_*dos 11 javascript dom

我正在开发像web应用程序这样的富文本编辑器,基本上是用javascript编写的XML编辑器.

我的javascript代码需要从contentEditable div容器中包装选择的节点.我正在使用MDC中描述的方法.但是因为我需要将div容器内容同步到我的XML DOM,所以我希望避免部分选择,如w3c范围中所述:

<BODY><H1>Title</H1><P>Blah xyz.</P></BODY

............^----------------^............

这个选择在H1内部开始并在P内部结束,我希望它完全包含H1,P.

是否有一种简单的方法可以扩展选择范围以完全覆盖部分选定的儿童?基本上我想使用range.surroundContents()而不会遇到异常.

(代码不需要与opera/IE一起使用)

Als*_*nde 9

查看MDC文档,我管理如下:

Selection.prototype.coverAll = function() {
    var ranges = [];
    for(var i=0; i<this.rangeCount; i++) {
        var range = this.getRangeAt(i);
        while(range.startContainer.nodeType == 3
              || range.startContainer.childNodes.length == 1)
            range.setStartBefore(range.startContainer);
        while(range.endContainer.nodeType == 3
              || range.endContainer.childNodes.length == 1)
            range.setEndAfter(range.endContainer);
        ranges.push(range);
    }
    this.removeAllRanges();
    for(var i=0; i<ranges.length; i++) {
        this.addRange(ranges[i]);
    }
    return;
};
Run Code Online (Sandbox Code Playgroud)

你可以在这里试试:http://jsfiddle.net/GFuX6/9/

编辑:已更新,以使浏览器正确显示增强选择.即使选择包含多个范围(使用Ctrl),它也能满足您的要求.

要使多个部分节点粗体,这是一个解决方案:

Selection.prototype.boldinize = function() {
    this.coverAll();
    for(var i=0; i<this.rangeCount; i++) {
        var range = this.getRangeAt(i);
        var parent = range.commonAncestorContainer;
        var b = document.createElement('b');
        if(parent.nodeType == 3) {
            range.surroundContents(b);
        } else {
            var content = range.extractContents();
            b.appendChild(content);
            range.insertNode(b);
        }
    }
};
Run Code Online (Sandbox Code Playgroud)