序列化 html:在选定文本周围放置 span 元素,同时保留 HTML 结构

Serializing html: placing span elements around selected text while preserving the HTML structure

我正在尝试制作一个文本荧光笔,教师可以在其中 select 一系列文本,以便学生可以跟进。文本格式为 HTML,因此有 <p><b><em> 等...元素。

为了突出显示文本范围,我将范围包装在 span 元素中。

问题:

https://jsfiddle.net/7fedkobr/1/

这是带有一些 HTML 标记的句子:

<p>The <b>quick</b> brown fox jumps over the <em>lazy</em> dog</p>

当我 select 像 'The' 这样的词时,它被包裹在 <span> 中,砰,没问题。

当我尝试 select 任何 html 标签时,问题就来了...例如,如果我 select 整个句子,那么我会失去所有标记。

我在找什么

一种序列化 span 的方法,使它们位于 html 元素之间并包裹所有文本。

使用前面的示例:如果我 select 上面的整个句子,那么我将得到以下输出:

<p><span>The </span><b><span>quick</span></b><span> brown fox jumps over the </span><em><span>lazy</span></em><span> dog</span></p>

问:

有这种连载的方法吗?我在 jQuery 文档中找不到任何内容,我问过的几个人都被难住了。

我认为你不需要 jquery,简单的 CSS 就可以了:

*::selection { background-color: yellow !important; }

关键是要用range.extractContents()。文档说明了满足您需求的最重要部分:

Partially selected nodes are cloned to include the parent tags necessary to make the document fragment valid.

document.getElementById('test').addEventListener('mouseup', function() {
    var range = window.getSelection().getRangeAt(0),
        span = document.createElement('span');

    span.className = 'highlight';
    span.appendChild(range.extractContents());
    range.insertNode(span);
});
.highlight { background-color: yellow; }
<div id="test">
    Select any part of <b>this sentence and</b> and then move the mouse to a new location.
</div>

您可以在下图中看到,选择的结果 HTML 完全符合您的要求: