记得去年工作中遇到老旧IE和现代浏览器JS关于DOM操作兼容性问题时,在chrome、IE、Firefox上测试getElementsByTagName返回的值,问题出现了,chrome和opera下返回的都是NodeList对象,而IE和Firefox返回的则是HTMLCollection对象。当时去查了资料,很多文章说IE和Firefox没按规范来,可前段日子我无意中又碰到了类似问题,浏览器(chrome、IE、Firefox)一测,全部返回HTMLCollection,我和我的小伙伴们都惊呆了,是规范有问题还是chrome也随大流了?翻开较新版神书《Javascript高级程序设计》一看,getElementsByTagName返回NodeList,但强调了在HTML文档中,返回一个HTMLCollection对象。顺便也测了下HTML5添加的getElementByClassname,神书说返回是NodeList,其实浏览器纷纷返回HTMLCollection。其实上述两个差别其实不大,他们都是动态的,但正因为此,每次访问NodeList和HTMLCollection的时候都会运行一次基于文档的查询,所以多次访问这些对象会影响性能。不要写下面那样的代码,会导致无限循环:
var divs = document.getElementByTagName("div"), i, div; for (i = 0; i < divs.length; i++) { div = document.createElement("div"); document.body.appendChild(div); }
稍作修改,就能避免无限循环
var divs = document.getElementByTagName("div"), i, len, div; for (i = 0;len=divs.length; i < len; i++) { div = document.createElement("div"); document.body.appendChild(div); }
上面就是设了一个len变量并初始化了它的值,说到底就是缓存了divs.length的值,在编写js代码中这种小技术很有用,这边的避免无限循环,还有能避免重复的dom遍历,既减少代码开销又提升了性能。
放一段jquery的例子
// 糟糕 h = $('#element').height(); $('#element').css('height',h-20); // 建议 $element = $('#element'); h = $element.height(); $element.css('height',h-20);
以上只是做个记录,顺便吐槽下前端的碎片化,各种内核的浏览器、各种终端、各种规范的无尽修改和难以确立。。。如有错误欢迎指出和讨论