开发者

How to traverse dom elements in raw JavaScript?

I do everything in jQuery bu开发者_如何学编程t now am going back to learn JavaScript proper. So how could I do the equivalent of this in vanilla js:

$('ul li a', '#myDiv').hide();


var as = document.querySelectorAll("#myDiv ul li a"),
    forEach = Array.prototype.forEach;

forEach.call(as, function(a) {
  a.style.display = "none";
});

Live Example

.getElementById, .querySelectorAll, .forEach, .call

This works on all modern browsers and only breaks on legacy browsers (like IE8).

You don't want to do cross browser compliance by hand, you should use a DOM shim for that.

You can use the ES5-shim for .forEach support. and you can find a querySelectorAll polyfill here which uses Sizzle.

For detailed browser support see

  • can I use querySelectorAll
  • ES5 compatibility table

Don't listen to those guys complaining about browser compliance. Just slap on a whole bunch of polyfills using Modernizr and friends and then you can forget about IE!


Don't rely on querySelectorAll(). It doesn't work in IE <= 7 or FF 3. If you want to use Vanilla JS you need to learn how to write browser compatible code:

(function(){
    var myDiv = document.getElementById('myDiv');

    // Use querySelectorAll if it exists
    // This includes all modern browsers
    if(myDiv.querySelectorAll){
        as = myDiv.querySelectorAll('ul li a');
        for(var i = 0; i < as.length; i++)
            as[i].style.display = 'none';
        return;
    }

    // Otherwise do it the slower way in order to support older browsers

    // uls contains a live list of ul elements 
    // that are within the element with id 'myDiv'
    var uls = myDiv.getElementsByTagName('ul');

    var lis = [];
    for(var i = 0; i < uls.length; i++){
        var l = uls[i].getElementsByTagName('li');
        // l is a live list of lis
        for(var j = 0; j < l.length; j++)
           lis.push(l[j]);
    }
    // lis is an array of all lis which are within uls 
    //within the element with id 'myDiv'

    var as = [];
    for(var i = 0; i < lis.length; i++){
        var a = lis[i].getElementsByTagName('a');
        // a is a live list of anchors
        for(var j = 0; j < a.length; j++)
           a[j].style.display = 'none'; // Hide each one
    }
})();

Here is a JSFiddle. Just so you're aware, getElementsByClassName() is another commonly used method of traversal which needs an alternative approach if it's not available (IE <= 8)


Since a UL element can only have LI as children, the fastest POJS method is to get all the ULs then all the As:

function doStuff() {
  var uls = document.getElementsByTagName('ul');
  var as;
  for (var i=0, iLen=uls.length; i<iLen; i++) {
    as = uls[i].geElementsByTagName('a');

    for (var j=0, jLen=as.length; j<jLen; j++) {
      as[j].style.display = 'none';
    }
  }
}

There doesn't seem any point to a querySelectorAll solution since the above is likely faster, not much more code and will work in every browser back to IE 4.


Good old document.getElementById or document.getElementsByTagName should get you started.


You can use querySelectorAll to find the elements, though keep in mind jQuery probably uses extra tricks for compatibility and so this may behave differently.

Then you could iterate over that list (code shown on the NodeList documentation page, linked from the above page) and set each element's element.style.display = "none".

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜