程序员人生 网站导航

document.querySelector()和document.querySelectorAll()方

栏目:jscript时间:2014-02-16 11:46:40

在css中对特定的元素设置样式离不开选择符的使用,现在一些大的javascript框架也常用选择符来获取特定的元素,如jQuery。W3c规范定义了两个新的方法(querySelectorAll和querySelectorAll)来获取元素节点,这两个方法都接受选择符作为自己的参数。Nicholas在他的《High Performance JavaScript》一书中对这两个方法作了简要介绍,并对其性能作了比较,与传统获取元素节点的方法相比,其性能明显偏优。让我们从下面这个例子说起。

<table id="score">  <thead>    <tr>      <th>Test</th>      <th>Result	  </th>	  </tr>	  </thead>  <tfoot>    <tr>      <th>Average	  </th>      <td>82%	  </td></tr></tfoot>  <tbody>    <tr>      <td>A</td>      <td>87%</td>	</tr>   <tr>      <td>A</td>      <td>87%</td>	</tr>	<tr>      <td>A</td>      <td>87%</td>	</tr>	…	</tbody></table>

上面的1000行表格中,要获取每行包含成绩的单元格,传统意义上,我们使用以下的方法:

var table = document.getElementById("score");var groups = table.tBodies;var rows = null;var cells = [];for (var i = 0; i < groups.length; i++) {  rows = groups[i].rows;  for (var j = 0; j < rows.length; j++) {    cells.push(rows[j].cells[1]);  }}

使用w3c提供的新方法,仅一行代码即可完成任务,而且速度很快。

var cells = document.querySelectorAll("#score>tbody>tr>td:nth-of-type(2)");

我们可以使用《javascript设计模式》一书中提供的一个“方法性能分析器”来比较这两个方法的性能,方法如下:

var MethodProfiler = function(component) {  this.component = component;  this.timers = {};  this.log = document.createElement("ul");  var body = document.body;  body.insertBefore(this.log,body.firstChild);  for(var key in this.component) {    // Ensure that the property is a function.    if(typeof this.component[key] !== 'function') {      continue;    }    // Add the method.    var that = this;    (function(methodName) {      that[methodName] = function() {        that.startTimer(methodName);        var returnValue = that.component[methodName].apply(that.component,          arguments);        that.displayTime(methodName, that.getElapsedTime(methodName));        return returnValue;      };    })(key); }};MethodProfiler.prototype = {  startTimer: function(methodName) {    this.timers[methodName] = (new Date()).getTime();  },  getElapsedTime: function(methodName) {    return (new Date()).getTime() - this.timers[methodName];  },  displayTime: function(methodName, time) {  	var li = document.createElement("li");	var text = document.createTextNode(methodName + ': ' + time + ' ms');    li.appendChild(text);	this.log.appendChild(li);  }};

然后将这两个方法写入一个对象之中,并用性能分析器对它们进行比较.

var obj = {	getElementByTradition:function(){		var table = document.getElementById("score");		var groups = table.tBodies;		var cells = [];		for (var i = 0; i < groups.length; i++) {		  rows = groups[i].rows;		  for (var j = 0; j < rows.length; j++) { 			cells.push(rows[j].cells[1]); 		  } 		} 	}, 	querySelectorAll:function(){ 			var cells = document.querySelectorAll("#score>tbody>tr>td:nth-of-type(2)");		}}var obj = new MethodProfiler(obj);obj.getElementByTradition();obj.querySelectorAll();

查看示例,我们很清楚的看到,新的方法不仅使用简单,而且性能明显优于我们传统的方法。注意,尽管IE8已经支持这些方法,但是IE8并不支持nth-of-type()选择器(详情可参考Compatibility table: CSS3 Selectors),所以在IE8中会抛出错误信息。

当调用document.querySelectorAll()方法时,将返回节点数种的第一个元素节点,如果没有匹配的节点,将返回null,如:

<div id="fooid=">      <p class=id="warningid=">This is a sample warning</p>      <p class=id="errorid=">This is a sample error</p> </div> <div id=id="barid=">      <p>...</p> </div>

使用上面的html,调用以下方法将返回id属性为foo的元素。

var obj = document.querySelector("#foo, #bar");alert(obj.innerHTML);//foo

如果去掉id属性为foo的元素,调用上面的方法将返回:bar。该方法按照参数中传递的选择符进行查找,如果找到则终止并返回该元素,否则返回null。

调用document.querySelectorAll()方法将按顺序返回包含在节点树中所有匹配的元素,如:

var res = document.querySelectorAll("p.warning, p.error");

上面的res中将选泽文档中class为“error”或“warning”的所有p元素。

尽管这两个方法简单易用,而且性能较高,但是也只有有限的浏览器支持这些方法,如IE8、FF3.5、Safari3.1、chrome1、opera10。我们可以在一些应用程序中按如下的方法试着使用它们:

if(document. querySelector){	var res = document.querySelectorAll("p.warning, p.error");}else{	//传统的方法;}

本文只是对这两个方法作一个简要的探讨,详情可以了解w3c了解更多。

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐