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 select
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.
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.
You can use this to unwrap your content.
$(".highlightYellow").contents().unwrap();
Demo: http://jsfiddle.net/R4hfa/
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?