On finding a text node (nodeType = 3), how to tinker with its HTML?
In the sense, suppose the text node's value (data or textContent) is This is textual content
, how to surround this with HTML - say a bold tag...make it This is textual content
.
Changing the textContent
writes out the HTML tags as well - <b>This is textual content</b>
How to make it render as This is textual content
.
Javascript / Jquery
Your question seems fairly raw DOM, but you've mentioned jQuery.
You can create the b
element, insert it before the text node, and then move the text node into it (live example):
function wrapNode(textNode, tagName) {
var wrapper = document.createElement(tagName);
textNode.parentNode.insertBefore(wrapper, textNode);
wrapper.appendChild(textNode);
return wrapper;
}
Another way is to manipulate the innerHTML
property of the text node's parent Element
, but if you do that note that any descendant elements you update in that way are replaced (so the new ones won't have the event handlers and such attached to the old ones).
Further reading:
jQuery mostly doesn't give you the raw text nodes, it's more Element
-focussed. But you might look at its wrap
, wrapAll
, and wrapInner
functions. wrapInner
is probably closest to what you want (live example):
$(parent_element_selector).click(function() {
$(this).wrapInner("<b>").unbind("click");
});
With jQuery you can use .wrapInner()
to add a tag around some text. For example, with the following HTML
<span>Text goes here</span>
You can use the following jQuery code to add <b>
tags
$('span').wrapInner('<b>');
This results in the following HTML:
<span><b>Text goes here</b></span>
Use $(selector).html('<strong>Something here</strong>');
or
create a class in CSS and then use addClass();
to the parent of the text
You could also try it this way:
HTML
<div id="test">
This is textual content
</div>
JavaScript
$('#test').wrapInner('<strong>');
That will surround everything inside #test
with a strong
tag.
To extend T.J's answer to better fit the OP's requirement, the provided function cannot be called within a loop (looping through nodes).
Personally, I had to convert all direct text nodes into spans, much like the OP hinted at (by referencing nodeType==3
).
The problem is that when converting the nodes inside a loop, it throws off the index! Here's some fine-tuned code that converts all text nodes into wrapped nodes (optimized):
for(var txtnodes=[],nodes=XXXX.childNodes,i=0,j=nodes.length;i<j;i++) {
if(nodes[i].nodeType==3) txtnodes[txtnodes.length] = nodes[i];
}
for(var m=0,n=txtnodes.length;m<n;m++) {
var span = document.createElement('span');
pg.insertBefore(span,txtnodes[m]);
span.appendChild(txtnodes[m]);
}
This function effectively "saves them for later" and converts them after the fact. The variable declarations are all compacted and inline, and all the loops are optimized for long node trees.
There aren't any other articles on Google about this topic, so happy coding to any future adventurers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With