Merging Text Nodes Together After Inserting Span

泪湿孤枕 提交于 2019-12-17 22:44:49

问题


I have an extension where I am storing/retrieving a section of the DOM structure (always a selection of text on the screen) the user has selected. When I am storing a selection, I enclose the section in a SPAN tag, and highlight the text in yellow. This causes the DOM structure around the selected text to split up into various text nodes. This causes a problem for me as when I try to restore this selection (without refreshing the page) it causes problems as the DOM structure has been modified.

My question is how do I prevent the DOM structure from splitting up after inserting the SPAN? If this cannot be achieved, how would I reassemble the DOM structure after removing the SPAN tag to its original state?

//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>

回答1:


You can use this to unwrap your content.

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

Demo: http://jsfiddle.net/R4hfa/




回答2:


Use element.normalize().

After you remove the span you inserted, you can use the element.normalize() method to merge the extra text nodes that were created as a result of the insertion/removal of the span. The normalize() method puts the specified element and all of its subtree into a "normalized" form (i.e. no text nodes in the subtree are empty and there are no adjacent text nodes). Found, thanks to @tcovo's comment.

Text nodes inside of an element are broken apart if you insert nodes and then remove them. Unfortunately they don't automatically re-merge once the extra node is removed. To answer peoples' questions as to "why" this matters, it usually causes issues when working with text highlighting in your UI.




回答3:


The very act of inserting a <span> tag will alter the DOM. That's, somewhat by definition, what you're doing when you call surroundContents(). You can't add a span tag without altering the DOM which includes splitting text nodes and adding new elements for the span.

Further, unless the selected text includes only whole text nodes and the selection never starts/stops in the middle of a text node, you will have to split text nodes to put the span in the right place. When you later remove the span tags, you will have extra text nodes. That shouldn't really matter to anything, but if you really think you have to get the split text nodes back to the way they were, I can think of a couple options:

1) Save the original parentNode before the span is inserted into it. Clone it, add your span to the clone, replace the original node with the clone and save the original. When you want to restore, put the original back and remove the cloned one.

2) When you remove the span, run a function that looks for neighboring text nodes and combine them.

3) Figure out why it matters that there are more text nodes afterwards than there were before because this should not matter to any code or display.




回答4:


When using normalize() pay attention! It will strip away nodes like <br/> and will alter the text and its visualisation.

normalize() is good, but it has its drawbacks.

So <p>"this is an "<br/>"example"</p> will turn into <p>this is an example</p>

Is there a way to use normalize() but keeping the <br/>s?



来源:https://stackoverflow.com/questions/9849316/merging-text-nodes-together-after-inserting-span

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!