Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to modify the HTML of a text node (type 3) / how to wrap it in an HTML span

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

like image 648
Sameet Avatar asked Nov 03 '11 14:11

Sameet


5 Answers

Your question seems fairly raw DOM, but you've mentioned jQuery.

Raw DOM stuff:

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:

  • DOM2 Core spec - very widely supported
  • DOM2 HTML spec - very widely supported
  • DOM3 Core spec - mostly supported, but you need to feature-detect some things
  • HTML5 DOM interfaces - support varies

jQuery:

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");
});
like image 79
T.J. Crowder Avatar answered Oct 17 '22 10:10

T.J. Crowder


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>
like image 21
a'r Avatar answered Oct 17 '22 09:10

a'r


Use $(selector).html('<strong>Something here</strong>');

or

create a class in CSS and then use addClass(); to the parent of the text

like image 40
Manse Avatar answered Oct 17 '22 11:10

Manse


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.

like image 2
arb Avatar answered Oct 17 '22 09:10

arb


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.

like image 1
Aaron Gillion Avatar answered Oct 17 '22 09:10

Aaron Gillion