开发者

convert some jQuery based code to native javascript, is it possible for this case?

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";
    });
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜