webpages - khan academy javascript html




Finding the DOM element with specific text and modify it (4)

I'm trying to figure out how to, in raw javascript (no jQuery, etc.), find an element with specific text and modify that text.

My first incarnation of the solution... is less than adequate. What I did was basically:

var x = document.body.innerHTML;
x.replace(/regular-expression/,"text");
document.body.innerHTML = x;

Naively I thought I succeeded with flying colors, especially since it was so simple. So then I added an image to my example and thought I could check every 5 seconds (because this string may enter the DOM dynamically)... and the image flickered every 5 seconds.

Oops.

So, there has to be a correct way to do this. A way that specifically singles out a specific DOM element and updates the text portion of that DOM element.

Now, there's always "recursively search through the children till you find the deepest child with the string" approach, which I want to avoid. And even then, I'm skeptical about "changing the innerHTML to something different" being the correct way to update a DOM element.

So, what's the correct way to search through the DOM for a string? And what's the correct way to update a DOM element's text?


Now, there's always "recursively search through the children till you find the deepest child with the string" approach, which I want to avoid.

I want to search for an element in an unordered random list. Now, there's a "go through all the elements till you find what you're looking for approach", which I want to avoid.

Old-timer magno tape, record, listen, meditate.

Btw, see: Find and replace text with JavaScript on James Padolsey's blog


Don't use innerHTML with a regular expression, it will almost certainly fail for non-trivial content. Also, there are still differences in how browsers generate it from the live DOM. Replacing the innerHTML will also remove any event listeners added as element properties (i.e. like element.onclick = fn).

It is best if you can have the string enclosed in an element with an attribute or property you can search on (id, class, etc.) but failing that, a search of text nodes is the best approach.

Edit

Attempting a general purpose text selection function for an HTML document may result in a very complex algorithm since the string could be part of a complex structure, e.g.:

<h1>Some <span class="foo"><em>s</em>pecial</span> heading</h1>

Searching for the string "special heading" is tricky as it is split over 2 elements. Wrapping it another element (say for highlighting) is also not trivial since the resulting DOM structure must be valid. For example, the text matching "some special" in the above could be wrapped in a span but not a div.

Any such function must be accompanied by documentation stating its limitations and most appropriate use.


Forget regular expressions.

Iterate over each text node (and doing it recursively will be the most elegant) and modify the text nodes if the text is found. If just looking for a string, you can use indexOf().


x.replace(/regular-expression/,"text");

will return a value so

var y = x.replace(/regular-expression/,"text");

now you can assign new value.

document.body.innerHTML = y;

Bu you want to think about this, you dont't want to get the whole body just to change one small piece of code, why not get the content of a div or any element and so on

example:

<p id='paragraph'>
    ... some text here ...
</p>

now you can use javascript

var para = document.getElementById('paragraph').innerHTML;
var newPara = para.replace(/regex/,'new content');

para.innerHTML = newPara;

This should be the simplest way.





text