getElementsByTagName vs selectNodes效率 及兼容的selectNodes实现


Posted in Javascript onFebruary 26, 2010

于是就测试了下:

var stringToDom=function(text) { 
var doc; 
if(window.ActiveXObject) { 
doc = new ActiveXObject("MSXML2.DOMDocument"); 
doc.loadXML(text).documentElement; 
} else { 
doc = (new DOMParser()).parseFromString(text,"text/xml"); 
} 
return doc; 
} 
var xmlDoc=stringToDom("<body><a href='a'>a</a><a href='b'>b</a></body>"), 
c, 
d1=new Date(); 
for(var i=0;i<100000;i++){ 
c=xmlDoc.getElementsByTagName("a"); 
} 
document.write("getElementsByTagName: ",new Date()-d1); 
d1=new Date(); 
try{ 
for(var i=0;i<100000;i++){ 
c=xmlDoc.selectNodes("a"); 
} 
document.write("<br/>selectNodes: ",new Date()-d1); 
}catch(ex){document.write("<br/>error:"+ex)}

在IE下selectNodes还是快多了,
可以FF下却没有这个方法,google了下,找了方法,使用XPathEvaluator来实现,下面是具体实现,不过效率就不太理想了:
if (!window.ActiveXObject) { 
(function(){ 
var oEvaluator=new XPathEvaluator(),oResult; 
XMLDocument.prototype.selectNodes = function(sXPath) { 
oResult = oEvaluator.evaluate(sXPath, this, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); 
var aNodes = []; 
if (oResult != null) { 
var oElement = oResult.iterateNext(); 
while (oElement) { 
aNodes[aNodes.length]=oElement; 
oElement = oResult.iterateNext(); 
} 
} 
return aNodes; 
} 
})() 
}

evaluate(xpathExpression, contextNode, namespaceResolver, resultType, result);
Returns an XPathResult based on an XPath expression and other given parameters.
xpathExpression is a string representing the XPath to be evaluated.
contextNode specifies the context node for the query (see the [http://www.w3.org/TR/xpath XPath specification). It's common to pass document as the context node.
namespaceResolver is a function that will be passed any namespace prefixes and should return a string representing the namespace URI associated with that prefix. It will be used to resolve prefixes within the XPath itself, so that they can be matched with the document. null is common for HTML documents or when no namespace prefixes are used.
resultType is an integer that corresponds to the type of result XPathResult to return. Use named constant properties, such as XPathResult.ANY_TYPE, of the XPathResult constructor, which correspond to integers from 0 to 9.
result is an existing XPathResult to use for the results. null is the most common and will create a new XPathResult
完整的测试页面:
<!doctype HTML> 
<html> 
<head> 
<title>selectNodes&getElementsByTagName</title> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<meta name="author" content="sohighthesky"/> 
<meta name="Keywords" content="selectNodes vs getElementsByTagName"/> 
</head> 
<body> 
</body> 
<script type="text/javascript"> 
/* 
*author:sohighthesky -- http://www.cnblogs.com/sohighthesky 
*content: selectNodes vs getElementsByTagName 
*/ 
if (!window.ActiveXObject) { 
(function(){ 
var oEvaluator=new XPathEvaluator(),oResult; 
XMLDocument.prototype.selectNodes = function(sXPath) { 
oResult = oEvaluator.evaluate(sXPath, this, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); 
var aNodes = []; 
if (oResult != null) { 
var oElement = oResult.iterateNext(); 
while (oElement) { 
aNodes[aNodes.length]=oElement; 
oElement = oResult.iterateNext(); 
} 
} 
return aNodes; 
} 
XMLDocument.prototype.selectSingleNode = function(sXPath) { 
oResult = oEvaluator.evaluate(sXPath, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); 
// FIRST_ORDERED_NODE_TYPE returns the first match to the xpath. 
return oResult==null?null:oResult.singleNodeValue; 
} 
})() 
} 
var stringToDom=function(text) { 
var doc; 
if(window.ActiveXObject) { 
doc = new ActiveXObject("MSXML2.DOMDocument"); 
doc.loadXML(text).documentElement; 
} else { 
doc = (new DOMParser()).parseFromString(text,"text/xml"); 
} 
return doc; 
} 
var xmlDoc=stringToDom("<body><a href='a'>a</a><a href='b'>b</a></body>"), 
c, 
d1=new Date(); 
for(var i=0;i<100000;i++){ 
c=xmlDoc.getElementsByTagName("a"); 
} 
document.write("getElementsByTagName: ",new Date()-d1); 
d1=new Date(); 
try{ 
for(var i=0;i<100000;i++){ 
c=xmlDoc.selectNodes("a"); 
} 
document.write("<br/>selectNodes: ",new Date()-d1); 
}catch(ex){document.write("<br/>error:"+ex)} 
/* 
var n=xmlDoc.selectSingleNode("body/a"),doc=xmlDoc.selectSingleNode("body");//alert(n.childNodes[0].nodeValue) 
for(var i=0;i<10000;i++){ 
doc.appendChild(n.cloneNode(true)) 
} 
d1=new Date(); 
c=xmlDoc.getElementsByTagName("a"); 
document.write("<br/>getElementsByTagName: ",new Date()-d1); 
d1=new Date(); 
c=xmlDoc.selectNodes("a"); 
document.write("<br/>selectNodes: ",new Date()-d1); 
*/ 
</script> 
</html>
Javascript 相关文章推荐
javascript的console.log()用法小结
May 31 Javascript
window.print打印指定div指定网页指定区域的方法
Aug 04 Javascript
js实现仿阿里巴巴城市选择框效果实例
Jun 24 Javascript
通过设置CSS中的position属性来固定层的位置
Dec 14 Javascript
详解JS对象封装的常用方式
Dec 30 Javascript
让微信小程序支持ES6中Promise特性的方法详解
Jun 13 Javascript
JS实现问卷星自动填问卷脚本并在两秒自动提交功能
Jun 17 Javascript
使用javaScript实现鼠标拖拽事件
Apr 03 Javascript
js构造函数创建对象是否加new问题
Jan 22 Javascript
微信小程序实现同一页面取值的方法分析
Apr 30 Javascript
js实现动态时钟
Mar 12 Javascript
JS闭包原理及其使用场景解析
Dec 03 Javascript
JavaScript 空位补零实现代码
Feb 26 #Javascript
javascript replace()正则替换实现代码
Feb 26 #Javascript
javascript function调用时的参数检测常用办法
Feb 26 #Javascript
jquery1.4 教程二 ajax方法的改进
Feb 25 #Javascript
jquery 1.4.2发布!主要是性能与API
Feb 25 #Javascript
jQuery 方法大全方便学习参考
Feb 25 #Javascript
js 面向对象的技术创建高级 Web 应用程序
Feb 25 #Javascript
You might like
第十五节--Zend引擎的发展
2006/11/16 PHP
Windows IIS PHP 5.2 安装与配置方法
2009/06/08 PHP
Symfony2针对输入时间进行查询的方法分析
2017/06/28 PHP
php 利用socket发送GET,POST请求的实例代码
2020/07/04 PHP
基于jquery实现一个滚动的分步注册向导-附源码
2015/08/26 Javascript
点评js异步加载的4种方式
2015/12/22 Javascript
chrome浏览器如何断点调试异步加载的JS
2016/09/05 Javascript
JavaScript之cookie技术详解
2016/11/18 Javascript
bootstrap table动态加载数据示例代码
2017/03/25 Javascript
详解vue组件化开发-vuex状态管理库
2017/04/10 Javascript
JavaScript实现打印星型金字塔功能实例分析
2017/09/27 Javascript
使用 Javascript 实现浏览器推送提醒功能的示例
2017/11/03 Javascript
jQuery 实现左右两侧菜单添加、移除功能
2018/01/02 jQuery
VUE.CLI4.0配置多页面入口的实现
2019/11/25 Javascript
jQuery操作元素的内容和样式完整实例分析
2020/01/10 jQuery
js实现页面导航层级指示效果
2020/08/25 Javascript
jQuery-App输入框实现实时搜索
2020/11/19 jQuery
[14:00]DOTA2国际邀请赛史上最长大战 赛后专访B神
2013/08/10 DOTA
[04:52]2015国际邀请赛LGD战队晋级之路
2015/08/14 DOTA
Python利用ORM控制MongoDB(MongoEngine)的步骤全纪录
2018/09/13 Python
Python Django简单实现session登录注销过程详解
2019/08/06 Python
Python GUI自动化实现绕过验证码登录
2020/01/10 Python
利用css3径向渐变做一张优惠券的示例
2018/03/22 HTML / CSS
详解使用canvas保存网页为pdf文件支持跨域
2018/11/23 HTML / CSS
德国baby-markt婴儿用品瑞士网站:baby-markt.ch
2017/06/09 全球购物
Android面试题及答案
2015/09/04 面试题
应聘医学检验人员自荐信
2013/09/27 职场文书
思想品德自我鉴定
2013/10/12 职场文书
有关打架的检讨书
2014/01/25 职场文书
楼面经理岗位职责范本
2014/02/18 职场文书
最常使用的求职信
2014/05/25 职场文书
农民工讨薪标语
2014/06/26 职场文书
市委召开党的群众路线教育实践活动总结大会报告
2014/10/21 职场文书
毕业纪念册寄语大全
2015/02/26 职场文书
作文之亲情600字
2019/09/23 职场文书
Python Flask搭建yolov3目标检测系统详解流程
2021/11/07 Python