If you know a bit of CSS, it's easy to alter the style of an element. However, there might be times when you want to highlight just a word or two in a sentence or paragraph.

To do this, you must break up the original text node. As DOM: About Objects describes, the browser creates an element object for each HTML tag it encounters. And one property of an element is a "style" object. In other words:

Style is applied to elements, not text.

Because an element receives style, its text will be displayed similarly. To highlight a word or phrase, it must be moved out of the element's text node into a new element.

For example, click here to emphasize the concept above. The "click here" link breaks the paragraph's text up in just this way. Here's how it's done.

breaking up text nodes

We start with this — a simple paragraph containing a single text node:

<p>Style applies to elements, not text.</p>

We want to alter it to this — a paragraph with 2 text nodes interrupted by a new "I" element:

<p>Style applies to <i>elements</i>, not text.</p>

This requires two main bits of work. First, we need to separate the original text node into 3 pieces, broken at the boundaries of the word "elements". This function does that job.

function split_into_3 (s,s1) {  // s1 matches a part of s
 var a = [];   // create an empty array 
 var i = s.indexOf(s1);   // search s for the start of s1
 var l = s1.length;   // save s1's length
 a[0] = s.substr(0,i);   // save text before s1
 a[1] = s1;   // save s1
 a[2] = s.substr(i+l);   // save text after s1
 return a;   // return the array

It receives the original text and the word we're seeking:

and returns the separated pieces in an array:

Javascript provides a "split" method to accomplish the same thing:

function split_into_3 (s,s1) { // s1 matches part of s
 var a=s.split(s1); // split throws away the separator so we need to restore it
 a.splice( 1,0,s1 ); // insert at index 1, remove 0 elements
 return a; 

The 2nd bit of work is done by this function. It receives the ID of the element we want to alter, the word or phrase we want to find, and the new HTML element we plan to insert:

function insert_element_in_string( id, needle, new_E_name ) {

 var E = document.getElementById(id);  // find the element
 var haystack = E.firstChild.nodeValue;  // get its text
 var spart = split_into_3(haystack,needle);  // split text into 3 parts

 E.firstChild.nodeValue = spart[0];  // replace original text with 1st part

 // create element node and text node to store 2nd part
 var new_txt_node = document.createTextNode(spart[1]);  // put 2nd part in new textNode
 var new_E_node = document.createNode(new_E_name);  // create element node
 new_E_node.setAttribute("class","alter_elem");  // set style via class
 new_E_node.appendChild(new_txt_node);  // append text to new element
 E.insertBefore(new_E_node,E.childNodes[1]);  // insert element after original node

 // create another text node to store 3rd part
 new_txt_node = document.createTextNode(spart[2]);  // put 3rd part into a textNode
 E.insertBefore(new_txt_node,E.childNodes[2]);  // insert after new element

The code above is launched this way. (The paragraph's ID is "alter_P"):

insert_element_in_string("alter_P", "elements", "i")

inserting links

With a small change, the same code can turn a word or phrase into an active link. We add a new "target" parameter to "insert_element_in_string":

function insert_element_in_string( sID, s_part, new_E_name, target ) {

And we add this line to the function. It sets an "href" attribute if the element is an anchor:

if (new_E_name == "a") new_E_node.setAttribute("href",target);

When inserting an anchor, we tack on the "target" parameter:

insert_element_in_string("insert_A", "needle", "a", "needle.html")

Let's take it for a spin:

Among the haystack of these characters, this needle will become an active link.

Click here to turn "this needle" into a link.


Why would you want to do this?

Reacting to user choice on forms or in menus.