Javascript 添加<;h1>;围绕选择

Javascript 添加<;h1>;围绕选择,javascript,range,rangy,Javascript,Range,Rangy,我这里有一个JSFIDLE——我试图在整行的选择周围添加标记:“这里有一些内容,这里也有” 选择整行并释放鼠标按钮将进入处理程序,但使用setStartBefore()和setEndAfter()四舍五入开始和结束点会使我进入不同的开始和结束容器,因此环绕不起作用 如果我将“hereissomecontent”放在它自己的-请参见-然后我们转到同一个容器,那么h1插入就起作用了。但是我需要一个解决方案,在选择的内容周围放置标记,无论第一个短语是否在范围内 谢谢你的帮助 <div id="c

我这里有一个JSFIDLE——我试图在整行的选择周围添加
标记:“这里有一些内容,这里也有”

选择整行并释放鼠标按钮将进入处理程序,但使用setStartBefore()和setEndAfter()四舍五入开始和结束点会使我进入不同的开始和结束容器,因此环绕不起作用

如果我将“hereissomecontent”放在它自己的
-请参见-然后我们转到同一个容器,那么
h1
插入就起作用了。但是我需要一个解决方案,在选择的内容周围放置
标记,无论第一个短语是否在范围内

谢谢你的帮助

<div id="container">
     <div class="content" contenteditable="true">Here is some content<span class="red"> and here too</span></div>
</div>

这里有一些内容,这里也有

我想出了一个可行的解决办法。启动时,选定的文本范围可以处于四种状态之一:

startContainer in a span    endContainer in a span
         no                       no
         yes                      no
         no                       yes
         yes                      yes
我可以通过应用下面四个操作中的一个,用h1来包围它们:

  • 不要更改起始或结束容器;按原样应用h1
  • 将结束设置为focusNode父级之后
  • 将“开始”设置为锚点节点父节点之前
  • 将“结束”设置为focusNode父节点之后,将“开始”设置为anchorNode父节点之前
  • 因此,我通过这四个操作,将每一个应用到我的范围中,在每次操作之后,我查看canSurround()是否返回true。我停下来做环绕

    代码是:

    case "RTE_h1_icon" :
                    newNode = document.createElement("h1");
                    var sel = rangy.getSelection(); 
                    anchorParent = sel.anchorNode.parentNode;
                    focusParent = sel.focusNode.parentNode;
                    range = sel.getRangeAt(0);
    
                    if(range.canSurroundContents()) {  // no modification
                        range.surroundContents(newNode);
                        break;
                    }
                    range1 = range;
                    range1.setEndAfter(focusParent);  // adjust end
                    if(range1.canSurroundContents()) {
                        range1.surroundContents(newNode);
                        break;
                    }
    
                    range2 = range;
                    range2.setStartBefore(anchorParent);  // adjust start
                    if(range2.canSurroundContents()) {
                        range2.surroundContents(newNode);
                        break;
                    }
    
                    range3 = range;
                    range3.setStartBefore(anchorParent);  // adjust start
                    range3.setEndAfter(focusParent);      // and end
                    if(range3.canSurroundContents()) {
                        range3.surroundContents(newNode);
                        break;
                    }
                    break;
    
    如果有人有更好的解决方案,或者看到我所做的有问题,我会很高兴收到你的来信


    像这样谢谢你?或者像这样?谢谢,但这两个都不行。我将第一个分叉到jsfiddle.net/kpoqzqm6/1,并添加了一个canround()检查。这将返回false,如果我继续,环绕将失败,并显示“未能在“范围”上执行“surroundContents”:该范围已部分选择了非文本节点。我将第二个节点分叉到jsfiddle.net/510szd5m/2,并获得了相同的结果。