如何用HTML标签包装跨境DOM选择范围?

15 html javascript dom

现在我正在捕捉用户的文本选择s = window.getSelection()range = s.getRangeAt(0)(浏览器的撇开).每当选择一个<p>由,我可以很容易地调用range.surroundContents(document.createElement("em"))有选择的文本包装<em>标签.

但是,在这个例子中,

<p>This is the Foo paragraph.</p>
<p>This is the Bar paragraph.</p>
<p>This is the Baz paragraph.</p>
Run Code Online (Sandbox Code Playgroud)

当用户从使得文本选择FooBaz,我不能叫range.surroundContents:Firefox的失败,The boundary-points of a range does not meet specific requirements." code: "1因为选择是无效的HTML.

在那种情况下,我想以某种方式在DOM中获得以下状态:

<p>This is the <em>Foo paragraph.</em></p>
<p><em>This is the Bar paragraph.</em></p>
<p><em>This is the Baz</em> paragraph.</p>
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?


仅供参考:我一直在尝试RangeAPI,但我看不到实现这一结果的简单方法.同

var r = document.createRange();
r.setStart(range.startContainer, range.startOffset);
r.setEnd(range.endContainer, range.endOffset+40);
selection.addRange(r);
Run Code Online (Sandbox Code Playgroud)

我最终可以通过重新定位偏移来破解某些东西,但仅限于"开始"和"结束"容器!(即在这种情况下Bar段落,我该如何包装?)

小智 9

你有没有尝试过以下方法(这实际上是W3C规范中关于surroundContents应该做什么的描述):

var wrappingNode = document.createElement("div");
wrappingNode.appendChild(range.extractContents());
range.insertNode(wrappingNode);
Run Code Online (Sandbox Code Playgroud)


Mur*_* VP 1

也就是说,当您将 contentEditable=true 属性添加到这些段落的父级时,选择任何文本,甚至跨段落,然后进行调用

document.execCommand('italic', false, null);
Run Code Online (Sandbox Code Playgroud)

最后,如果需要,将 contentEditable 属性设置回 false。

顺便说一句,这也适用于 IE,除了进入可编辑模式,我认为它被称为 designMode 或其他东西,谷歌搜索它。