Consider this document fragment:
<div id="test">
<h1>An article about John</h1>
<p>The frist paragraph is about John.</p>
<p>The second paragraph contains a <a href="#">link to John's CV</a>.</p>
<div class="comments">
<h2>Comments to John's article</h2>
<ul>
<li>Some user asks John a question.</li>
<li>John responds.</li>
</ul>
</div>
</div>
I would like to replace every occurrence of the string "John" with the string "Peter". This could be done via HTML rewriting:
$('#test').html(function(i, v) {
return v.replace(/John/g, 'Peter');
});
Working demo: http://jsfiddle.net/v2yp5/
The above jQuery code looks simple and straight-forward, but this is deceiving because it is a lousy solution. HTML rewriting recreates all the DOM nodes inside the #test DIV. Subsequently, changes made on that DOM subtree programmatically (for instance "onevent"
handlers), or by the user (entered form fields) are not preserved.
So what would be an appropriate way to perform this task?
As a recommended alternative to document. write you could use DOM manipulation to directly query and add node elements to the DOM. This would be a better answer if it addressed the question of why document.
. write is considered a browser violation as it halts the parser from rendering the page.
How about a jQuery plugin version for a little code reduction?
http://jsfiddle.net/v2yp5/4/
jQuery.fn.textWalk = function( fn ) {
this.contents().each( jwalk );
function jwalk() {
var nn = this.nodeName.toLowerCase();
if( nn === '#text' ) {
fn.call( this );
} else if( this.nodeType === 1 && this.childNodes && this.childNodes[0] && nn !== 'script' && nn !== 'textarea' ) {
$(this).contents().each( jwalk );
}
}
return this;
};
$('#test').textWalk(function() {
this.data = this.data.replace('John','Peter');
});
Or do a little duck typing, and have an option to pass a couple strings for the replace:
http://jsfiddle.net/v2yp5/5/
jQuery.fn.textWalk = function( fn, str ) {
var func = jQuery.isFunction( fn );
this.contents().each( jwalk );
function jwalk() {
var nn = this.nodeName.toLowerCase();
if( nn === '#text' ) {
if( func ) {
fn.call( this );
} else {
this.data = this.data.replace( fn, str );
}
} else if( this.nodeType === 1 && this.childNodes && this.childNodes[0] && nn !== 'script' && nn !== 'textarea' ) {
$(this).contents().each( jwalk );
}
}
return this;
};
$('#test').textWalk(function() {
this.data = this.data.replace('John','Peter');
});
$('#test').textWalk( 'Peter', 'Bob' );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With