views:

151

answers:

3

Hello

i followed this snippet http://bytes.com/topic/javascript/answers/504399-get-all-text-nodes

 var xPathResult = document.evaluate(
 './/text()[normalize-space(.) != ""]',
 document.body, null,
 XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
 null ); for (var i = 0, l = xPathResult.snapshotLength; i < l; i++) { 
 var textNode = xPathResult.snapshotItem(i);
 textNode.data = textNode.data.replace(/somePattern/g, 'replacement');
 }

i want to replace certain patterns like for example |12| with a corresponding emoticon ! but when i do textNode.data.replace("|12|",'<.img src="favicon.ico"/>'); for example the text show is ..<.img src="favicon.ico"/>.. as i inspect the html i find that <.img src="favicon.ico"/> became escaped to &lt;img src="favicon.ico"/&gt; is it possible to prevent this and to let the image show ?? Thank You

Note: added extra point here &lt;.img src="favicon.ico"/&gt; in purpose

A: 

textNode.data is CDATA within the element. What you need is to replace within textNode.innerHTML

newtover
+4  A: 

Yes, data is always plain text. That means you don't have to worry about escaping characters in it, but it also means you can't throw markup like <img> into it.

The naïve way forward would be to replace over the innerHTML of the containing element instead of using the text interface. But that can quickly give you big problems, partly because writing back to the innerHTML means you're destroying and replacing every existing node inside the element (with accompanying annoyance if you've got event handlers or form values on them being destroyed), but also because simple string and regex processing cannot handle HTML properly. For example if you had the string |12| inside any attribute value, the replacement would make a big old mess.

Better: use splitText to chop the text nodes into bits at the edge of a pattern match, then replace the text representing that match with a new DOM element:

var pattern= /\|12\|/;
var node= /* Text node you want to replace strings in */;

while (match= pattern.exec(node.data)) {
    var img= document.createElement('img');
    img.src= 'favicon.ico';

    node= node.splitText(match.index);
    node= node.splitText(match[0].length);
    node.parentNode.replaceChild(img, node.previousSibling);
};

(Note that the XPath method of getting all text nodes isn't available on IE.)

bobince
This is definitely the better approach. Don't be seduced by innerHTML for this.
Tim Down
dont forget to create a loop that will do them all and not just the first one.
Jonathan Czitkovics
Yes, this loop replaces all occurrences of a string in a single Text node; you still need to loop over all Text nodes either using XPath or manual tree walking/`getElementsByTagName('*')` children.
bobince
A: 

Thanks For Help All :)) I Will be looping through all text nodes

It's a firefox Extension :D i never get near IE ! You guys are Great ! edit : install and try it :D https://addons.mozilla.org/en-US/firefox/addon/14455/

ünLoCo