peace folks, I have this small piece of jquery based code, that grabs all tags that has class "foo" and their childs and assign them some value, my question how could i get this working in the same exact way but not using jquery, but native javascript
jQuery.each(data.results, function(index, value) {
jQuery(".foo").find("*")
.andSelf()
.contents()
.filter(function(){
return this.nodeType === 3;
})
.filter(function(){
// Only match when contains 'simple string' anywhere in the text
if (value.origin != ""){
retur开发者_如何学编程n this.nodeValue === (value.origin);
}
})
.each(function(){
this.nodeValue = "assign me";
});});
technically it is native javascript, jQuery is written in javascript and you use javascript to access the objects and methods it sets up.
So the real question is "can you do this without using the JQuery include?"
Sure you can, but it would probably be much longer, harder to maintain, and buggier than using the jQuery.
It' hard to see what exactly you are trying to do here, but here are a couple of functions that might help you and an example of their use (as I understand your requirement)
function getTextNodes( el ) {
var nodes = [];
if( el.length ) { //perhaps a better test for an array/collection of objects is required here?
for( var i = 0, j = el.length; i < j; i++ ) {
//call this function with each item in the array/collection
nodes = nodes.concat( arguments.callee( el[i] ) );
}
return nodes;
}
for( var i = 0, j = el.childNodes.length; i < j; i++ ) {
var node = el.childNodes[i];
if( node.nodeType == 3 ) {
//ignore whitespace
if( /^\s+$/.test( node.nodeValue ) ) continue;
nodes.push( node );
} else {
//call this function with this child node
nodes = nodes.concat( arguments.callee( node ) );
}
}
return nodes;
};
function getByClassName( className ) {
//some browsers already have this function
if( document.getElementsByClassName ) {
return document.getElementsByClassName( className );
}
var els = [];
var candidates = document.getElementsByTagName( '*' );
for( var i = 0, j = candidates.length; i < j; i++ ) {
if( candidates[i].className.indexOf( className ) > -1 ) {
els.push( candidates[i] );
}
}
return els;
};
function trim( str ) {
return str.replace( /^\s+/, '' ).replace( /\s+$/, '' );
};
USE:
//grab all the textnodes in elements with class foo
var textNodes = getTextNodes( getByClassName( 'foo' ) );
//loop through the data performing your replacement
for( var key in data ) {
if( !data[key].origin ) continue;
for( var i = 0, j = textNodes.length; i < j; i++ ) {
if( trim( data[key].origin ) == trim( textNodes[i].nodeValue ) ) {
textNodes[i].nodeValue = 'assign me';
}
}
}
A couple of points on your original
- It's inefficient - for each loop of your data you find the textnodes in foo elements all over again, you only need to find them once
- Chaining in jQuery does allow very succinct code but doesn't make it understandable. I think the point above is as a result of wanting to chain everything
better jQuery
var textnodes = jQuery( ".foo" )
.find( "*" )
.andSelf()
.contents()
.filter( function() {
return this.nodeType === 3;
});
jQuery.each( data.results, function( index, value ) {
textnodes.filter( function() {
// Only match when contains 'simple string' anywhere in the text
if( value.origin != "" ) {
return this.nodeValue === (value.origin);
}
})
.each(function(){
this.nodeValue = "assign me";
});
});
精彩评论