JQuery/Javascript - Search DOM for text and insert HTML

12,864

Solution 1

There are native methods for finding text inside a document:

MSIE:textRange.findText()
Others: window.find()

Manipulate the given textRange if something was found.
Those methods should provide much more performance than the traversing of the whole document.

Example:

<html>
<head>

  <script>
  function fx(a,b)
  {
    if(window.find)
    {
      while(window.find(a))
      {
        var node=document.createElement('b');
            node.appendChild(document.createTextNode(b));
        var rng=window.getSelection().getRangeAt(0);
            rng.collapse(false);
            rng.insertNode(node);
      }
    }
    else if(document.body.createTextRange)
    {
      var rng=document.body.createTextRange();
      while(rng.findText(a))
      {
        rng.collapse(false);
        rng.pasteHTML('<b>'+b+'</b>');
      }
    }
  }
  </script>
</head>
<body onload="fx('cheese','is wonderful')">
<p>I've made a wonderful cheesecake with some <i>cheese</i> from my <u>chees</u>e-factory!</p>
</body>
</html>

Solution 2

This is crude and not the way to do it, but;

document.body.innerHTML = document.body.innerHTML.replace(/cheese/, 'cheese <b>is fantastic</b>');

Solution 3

You can use this with JQuery:

$('*:contains("cheese")').each(function (idx, elem) {
    var changed = $(elem).html().replace('cheese', 'cheese <b>is fantastic</b>');
    $(elem).html(changed);
});

I haven't tested this, but something along these lines should work.

Note that * will match all elements, even html, so you may want to use body *:contains(...) instead to make sure only elements that are descendants of the document body are looked at.

Share:
12,864
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    How do I search the DOM for a certain string in the document's text (say, "cheese") then insert some HTML immediately after that string (say, "< b >is fantastic< /b >").

    I have tried the following:

    for (var tag in document.innerHTML) {
        if (tag.matches(/cheese/) != undefined) {
            document.innerHTML.append(<b>is fantastic</b>
        }
    }
    

    (The above is more of an illustration of what I have tried, not the actual code. I expect the syntax is horribly wrong so please excuse any errors, they are not the problem).

    Cheers,

    Pete

  • Dr.Molle
    Dr.Molle over 13 years
    Hopefully "cheese" will not inside of element-attributes, CSS or JS.
  • Tim Down
    Tim Down over 13 years
    Wrapping the text once you've found it is non-trivial in non-IE browsers.
  • Dr.Molle
    Dr.Molle over 13 years
    The question is about appending not surrounding, that's trivial in non-IE-browsers too.
  • Tim Down
    Tim Down over 13 years
    Fair enough. I'm not convinced this will be as precise as the DOM traversal solution in terms of exactly where it puts these nodes that are being created, there's a case sensitivity issue to address and it messes with the user's selection, but it does work and is a valid alternative. +1.
  • Dr.Molle
    Dr.Molle over 13 years
    Both methods have parameters to set case-sensitivity, it's just a simple example not a finished solution.
  • Dragos
    Dragos over 11 years
    I stumbled on a similar problem and found your solution very helpful. Do you know how I could wrap the found text in a <b> tag, for example? I have done this in Firefox, but I'm stuck with IE8.
  • Dr.Molle
    Dr.Molle over 11 years
    The code above wraps the text in a <b/> and should work in IE8