Search code examples
javascripthtmldomdom-traversal

how to dynamically address a word/string with javascript in an html-document and then tag it?


I have an HTML-document:

<html>
  <body>
    <p>
      A funny joke:
      <ul>
        <li>do you know why six is afraid of seven?
        <li>because seven ate nine.
      </ul>
      Oh, so funny!
    </p>
  </body>
</html>

Now I want to identify the first occurence of "seven" and tag it with

<span id="link1" class="link">

How can this be accomplished?

Do you have to parse the DOM-tree or is it possible to get the whole code within the body-section and then search for the word?

In both cases, after I found the word somewhere, how do you identify it and change it's DOM-parent to span (I guess that's what has to be done) and then add the mentioned attributes?

It's not so much a code I would expect, but what methods or concepts will do the job.

And I am not so much intersted in a framework-solution but in a pure javascript way.


Solution

  • You need to find a DOM node with type TEXT_NODE (3) and containig your expected word. When you need to split a that node into three ones.

    First is a TEXT_NODE which contains a text before the word you search, second one is a SPAN node containing the word you search, and third one is another TEXT_NODE containing an original node's tail (all after searched word).

    Here is a source code...

    <html>
       <head>
          <style type="text/css">
             .link {
                color: red;
             }
          </style>
       </head>
      <body>
        <p>
          A funny joke:
          <ul>
            <li>do you know why six is afraid of seven?
            <li>because seven ate nine.
          </ul>
          Oh, so funny!
        </p>
        <script type="text/javascript">
           function search(where, what) {
             var children = where.childNodes;
             for(var i = 0, l = children.length; i < l; i++) {
                var child = children[i], pos;
                if(child.nodeType == 3 && (pos = child.nodeValue.indexOf(what)) != -1) { // a TEXT_NODE
                   var value = child.nodeValue;
                   var parent = child.parentNode;
                   var start = value.substring(0, pos);
                   var end = value.substring(pos + what.length);
                   var span = document.createElement('span');
    
                   child.nodeValue = start;
                   span.className = 'link';
                   span.id = 'link1';
                   span.innerHTML = what;
                   parent.appendChild(span);
                   parent.appendChild(document.createTextNode(end));
                   return true;
                } else
                   if(search(child, what))
                      break;
             }
             return false;
           }
           search(document.getElementsByTagName('body')[0], 'seven');
        </script>
      </body>
    </html>