1

Using Javascript/jQuery, I would like to find and replace all instances of "foo" to bar, but ignore any instances of "foo" that happen to be attribute values.

Example:

<p><a class="foo" id="foo" href="foo.html">foo</a>foo</a></p>

Should become

<p><a class="foo" id="foo" href="foo.html"><span class="fixed">bar</span></a></p>

This example is the problem I am running into....

<h3><a id="foo" name="foo">About foo</a></h3>

In that example, the attributes of the link get changed too

Hochmania
  • 65
  • 3
  • 9

1 Answers1

1

You can use .html(function) .replace() with RegExp /foo/g and replacement string "bar". If this within callback function does not contain .childNodes return text argument with .replace(/foo/g, "bar") chained, else iterate child nodes of element, match node where .nodeName is #text, replace .textContent of matched node. Use Node.replaceChild() to replace matched #text node with <span> element.

$("body *").html(function(_, text) {
  if (!this.children.length) {
    return text.replace(/foo/g, '<span class="fixed">bar</span>')
  }
  else {
    var el = this;
    for (var i = 0; i < el.childNodes.length; i++) {
      var node = el.childNodes[i];
      if (node.nodeName === "#text") {
        var span = document.createElement("span");
        span.textContent = node.textContent.replace(/foo/g, "bar");
        span.className = "fixed";
        node.parentNode.replaceChild(span, node);
      }
    }
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<p><a class="foo" id="foo" href="foo.html">foo</a>foo</p>
<h3><a id="foo" name="foo">About foo</a></h3>
guest271314
  • 1
  • 15
  • 104
  • 177
  • When I use that snippet, all the HTML within is stripped out, which I believe is because .text() is being used instead of .html() – Hochmania May 15 '17 at 16:38
  • @Hochmania See updated post. – guest271314 May 15 '17 at 17:16
  • Fixes one problem, but the span is inserted as text, instead of HTML. I want to wrap the string in a span, but unofortunately the span comes out as text. – Hochmania May 15 '17 at 17:34
  • What do you mean? Original Question is to replace text, not create element, yes? What happens to text node having `.textContent` set to `"foo"` that is child node of `

    ` element?

    – guest271314 May 15 '17 at 17:37
  • Sorry for confusion. In short, need to find string 'foo' and replace with 'bar'. Issue I have run into is if 'foo' exists in a HTML element class or id, the JS is replacing it and breaking markup. – Hochmania May 15 '17 at 17:42
  • @Hochmania See updated post. – guest271314 May 15 '17 at 17:54