插入跨度后合并文本节点

时间:2012-03-24 05:09:50

标签: javascript jquery google-chrome-extension

我有一个扩展程序,用于存储/检索用户选择的DOM结构的一部分(总是在屏幕上选择文本)。当我存储选择时,我将该部分包含在SPAN标记中,并以黄色突出显示该文本。这会导致所选文本周围的DOM结构拆分为各种文本节点。这对我来说是一个问题,因为当我尝试恢复此选择时(不刷新页面)它会导致问题,因为DOM结构已被修改。

我的问题是如何在插入SPAN后阻止DOM结构拆分?如果无法实现这一点,在将SPAN标记移至其原始状态后,如何重新组合DOM结构?

//Insert the span
var sel = restoreSelection(mootsOnPage[i].startXPath);
var range = sel.getRangeAt(0).cloneRange();
var newNode = document.createElement('span');
newNode.className = 'highlightYellow';
range.surroundContents(newNode); 


//Original DOM structure
<p>Hello there, how are you today</p>


//What the DOM looks like after insertion of SPAN
<p>
  "Hello there, "
  <span class="highlightYellow">how</span
  " are you today"
</p>

5 个答案:

答案 0 :(得分:74)

使用element.normalize()

删除插入的范围后,可以使用element.normalize()方法合并由于插入/删除范围而创建的额外文本节点。 normalize()方法将指定的元素及其所有子树放入&#34;标准化的&#34;形式(即子树中没有文本节点是空的,并且没有相邻的文本节点)。发现,感谢@ tcovo的评论。

如果插入节点然后将其删除,则元素内的文本节点会被拆分。不幸的是,一旦删除了额外的节点,他们就不会自动重新合并。回答民众的问题关于&#34;为什么&#34;的问题这很重要,它通常会导致在UI中使用文本突出显示时出现问题。

答案 1 :(得分:5)

插入<span>标记的行为将改变DOM。根据定义,这就是你在致电surroundContents()时所做的事情。您无法在不更改DOM的情况下添加span标记,其中包括拆分文本节点和为跨度添加新元素。

此外,除非所选文本仅包含整个文本节点,并且选择永远不会在文本节点的中间开始/停止,否则您必须拆分文本节点以将跨度放在正确的位置。稍后删除span标记时,将有额外的文本节点。这对任何事情都不重要,但如果你真的认为你必须让拆分文本节点恢复原状,我可以考虑几个选项:

1)在将span插入其中​​之前保存原始parentNode。克隆它,将您的span添加到克隆,用克隆替换原始节点并保存原始节点。如果要还原,请将原件放回原位并移除克隆的原件。

2)删除span时,运行一个查找相邻文本节点的函数并将它们组合起来。

3)弄清楚为什么事后有更多的文本节点比以前更重要,因为这对任何代码或显示都无关紧要。

答案 2 :(得分:2)

使用normalize()时要注意! 它将剥离<br/>之类的节点,并将改变文本及其可视化。

normalize()很好,但它有它的缺点。

因此<p>"this is an "<br/>"example"</p>将变为<p>this is an example</p>

有没有办法使用normalize()但保留<br/> s?

答案 3 :(得分:0)

您可以连接然后删除第二个节点

node1.textContent += node2.textContent;
node2.remove();

答案 4 :(得分:-7)

您可以使用它来解开您的内容。

$(".highlightYellow").contents().unwrap(); 

演示:http://jsfiddle.net/R4hfa/