jQuery选择器探讨进阶

标签: 前端开发 jQuery jQuery基础教程 jQuery框架编程进阶 jQuery深度学习 | 发表时间:2013-02-28 18:58 | 作者:tiegen.zhutg
出处:http://www.aliued.cn

jQuery 选择器探讨

在jQuery中,当用户把选择器表达式作为参数传递给$()函数时,jQery的Sizzle先对这个选择器表达式进行语法分析,然后再决定如何获得表达式所代表的这些元素。在框架底层,Sizzle应用了浏览器所支持的最高效的DOM 方法来获取一个节点列表(nodeList),这个节点列表是一个类似于数组的对象的DOM元素的集合。下面的列表展示了jQuery的Sizzle内部采用的浏览器DOM遍历方法和浏览器的支持情况:

  1. 1. .getElementById()  浏览器支持情况:IE 6+, Firefox 3+, Safari 3+, Chrome 4+, and Opera 10+;
  2. 2. .getElementsByTagName()  浏览器支持情况:IE 6+, Firefox 3+, Safari 3+,Chrome 4+, and Opera 10+;
  3. 3. .getElementsByClassName() 浏览器支持情况:IE 9+, Firefox 3+, Safari4+, Chrome 4+, and Opera 10+;
  4. 4. .querySelectorAll() (这个是浏览器内置的css选择符查询元素方法,比getElementsByTagName和getElementsByClassName效率要高很多。)浏览器支持情况:IE 8+, Firefox 3.5+, Safari 3+, Chrome 4+, and Opera 10+;

如果是最新版本的浏览器,ie8以上,Sizzle采用.querySelectorAll()方法来获取对应的DOM元素集,这个方法以CSS表达式为string参数,获取DOM元素的速度比其他3个方法更快更高效。当jQuery 选择器表达式中包含自定义选择符,比如eq() 或  :odd 或 :even,因为没有配对的CSS表达式,jQuery只能采用前3个方法(.getElementById(),.getElementsByTagName(),.getElementsByClassName() )来逐个遍历总元素集(通过 document.getElementsByTagName(‘*’)获得),再检验元素,最终获得对应于选择表达式的元素集,这种遍历查找性能消耗比较大。因此,如果不能用.querySelectorAll()直接获得对应的元素,采用另外3种方法获得元素集的效率要差一些,所以,在jqury中,一些选择器表达式普遍快于另外一些选择器表达式,把选择器中的伪类移到相应的方法中可以加速查找页面文档dom元素的时间。为了简单起见,我们把jQuery中用.getElementById (),.getElementsByTagName(),.getElementsByClassName() 这3个方法的结合来查找元素称为:循环和检验(loop and test)过程。

下面我们来看几个例子:

我们采用$(‘input[type="text"]‘)和$(‘input:text’)这两个表达式来检验上述论点。$(‘input[type="text"]‘),因为采用了CSS的属性表达式,所以Sizzle用.querySelectorAll()来查找元素,$(‘input:text’),采用了jQuery自定义的选择器表达式:text,.querySelectorAll()方法无法解析,所以Sizzle底层采用循环和检验(loop and test)过程。

结果如下图所示:

纵轴中的数字代表在规定时间内,表达式选择器方法可以被执行的次数,因此,数值越高,执行效率越好,代表执行时间越短,性能越好。在现代浏览器中,(Chrome 12, Firefox4, and Safari 5,IE 8+) ,CSS选择器表达式底层采用.querySelectorAll()方法,很好的实现了优势,平均而言,大概是自定义选择器表达式性能表现的2倍。但是,在ie7中,这两个选择器的性能表现差不多,这是因为在ie7环境下,Sizzle都采用了循环和检验(loop and test)过程累找到相应的元素,(因为ie7不支持.querySelectorAll()方法。),所以在编写jQuery的选择器函数进行事件注册时,要特别注意,可能你的代码在ie8以上执行正确,但在ie7中,$()函数返回的object.length将是0。比如下面这个列子的代码,在ie7下会导致执行错误:

$(document).ready(function() {
  var trigger = $('#filter_sample');
  var url = $('+ a',trigger).attr('href');
});

在ie6,ie7中,变量url的值将是undefined,因为ie7不支持.querySelectorAll()方法,而按.getElementsByTagName()方法解析上面的选择表达式得到的结果集为空,所以$(‘+ a’,trigger)在ie7下将得到一个空数组对象。自然对这个空数组取href属性,返回undefined了。所以, 在jQuery中,合理的编写选择表达式是十分重要的。

在浏览器中,$(‘input:eq(1)’)和$(‘input’).eq(1)的性能表现差异比较大:

从上图可知,甚至在ie7中,把:eq()选择器移出表达式,转而采用.eq()方法,性能也有100%的提升。为何如此?当jQuery遇到单个id,标签名,类名,选择器就会以坐快车的形式快速调用浏览器支持的DOM方法,在上面的例子中,使用简单的input标签作为$() 函数的参数,将会导致一个非常快速的查询。然后.eq(1)方法简单的调用数组函数来取回该元素集的第2个元素。

总的来说,做为一个常见的规则,我们应该尽量使用符合CSS语法规范的CSS选择器表达式,以此来避免使用jQuery自定义的选择器表达式,在jQuery选择器性能测试方面,可以采用 http://jsperf.com/这个在线工具来检验哪种编写方法对性能的改进影响更大。

另外2个跟jQuery选择器有关的性能问题是尽量 采用链式调用来操作缓存选择器结果集。因为每一个$()的调用都会导致一次新的查找,所以,采用链式调用和设置变量缓存结果集,减少查找,提升性能。

链式调用示例:

$(document).ready(function() {
  function stripe() {
    $('#news').find('tr.alt').removeClass('alt').end().find('tbody').each(function() {
        $(this).children(':visible').has('td').filter(':group(3)').addClass('alt');
   });
  }
 stripe();
});

通过链式调用,采用find(),end(),children(),has,filter()等方法,来过滤结果集,减少$()查找方法调用,提升性能。

缓存结果集示例:

$(document).ready(function() {
   var $news = $('#news');
   function stripe() {
      $news.find('tr.alt').removeClass('alt');
      $news.find('tbody').each(function() {
         $(this).children(':visible').has('td').filter(':group(3)').addClass('alt');
      });
   }
   stripe();
});

通过声明$news变量缓存$(‘#news’)结果集,从而提升后面结果集对象调用方法的性能。

相关 [jquery 选择 探讨] 推荐:

jQuery选择器探讨进阶

- - 阿里巴巴(中国站)用户体验设计部博客
jQuery 选择器探讨. 在jQuery中,当用户把选择器表达式作为参数传递给$()函数时,jQery的Sizzle先对这个选择器表达式进行语法分析,然后再决定如何获得表达式所代表的这些元素. 在框架底层,Sizzle应用了浏览器所支持的最高效的DOM 方法来获取一个节点列表(nodeList),这个节点列表是一个类似于数组的对象的DOM元素的集合.

JQuery 选择器

- - CSDN博客Web前端推荐文章
}

点击我

.    像上面这样把JavaSript代码和HTML代码混杂在一起的做法同样也非常不妥,因为它并没有将网页内容和行为分离,所以才有JQuery选择器的学习.

点击我

. //给class为demo的元素添加行为.

Hadoop版本选择探讨

- - 董的博客
Dong | 新浪微博: 西成懂 | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及 版权声明. 网址: http://dongxicheng.org/mapreduce-nextgen/how-to-select-hadoop-versions/. 由于Hadoop版本混乱多变,因此,Hadoop的版本选择问题一直令很多初级用户苦恼.

jquery选择器总结[初步]

- - CSDN博客推荐文章
  Jquery是继prototype之后又一个优秀的Javascript框架. 它是轻量级的js库 ,它兼容CSS3,还兼容各种浏览器. jQuery使用户能更方便地处理HTML documents、events、实现动画效果,并且方便地为网站提供AJAX交互. jQuery能够使用户的html页面保持代码和html内容分离,也就是说,不用再在html里面插入一堆js来调用命令了,只需定义id即可.

jQuery 和 prototype 选择器的使用与注意事项

- - ITeye博客
我的博客求点击: http://yysource.sourceforge.net/?p=36. 如果是根据id(假设id="myid")选择,. jQuery的用法为(这里用jQuery代替$):jQuery("#myid"); 则返回一个数组. prototype 的用法为:$("myid"); 返回结果为一个Element对象.

Chosen—强大的jquery模拟选择框插件

- - ria之家--RIA三部曲:jquery、ext、flex
很久没写jquery相关的内容了. 今天明河向大家推荐个相当不错的模拟选择框插件:Chosen. Chosen提供了suggest功能,强大的是实现了选项分组和多选关键词处理. 设置 data-placeholder=”",即可. 如果不存在data-placeholder,组件会自动设置默认文本为“Select Some Option”或“”Select Some Options”.

jquery mobile搭配REST是不错的选择

- - ITeye博客
现在,jquery mobile由于可以使用HTML5去 编写移动网页,因此如果是普通的网站,. 想搞个移动版本之类的话,可以尝试用jquery mobile,比如有些功能,需要返回给. 移动端的话,可以使用后端REST的风格,以JSON形式返回给前端,然后jquery mobile. 有利用ajax发起向后端拿到REST返回的结果,在前端解析,效果是不错的.

Jquery:强大的选择器<一> - net小民工

- - 博客园_首页
   今天回家之后,学习的是Jquery的选择器. 选择器作为Jquery的优势之一,确实让我感觉到了它的强大. Jquery选择器分为基本选择器、层次选择器、过滤选择器和表单选择器,下面我一一介绍这四种选择器.    看了书中关于选择器的介绍,我才知道,自己平日里用的大部分都是基本选择器. 基本选择器中包含id选择器、class选择器、标签选择器、复合选择器和“*”选择器.

[探讨]分布式文件系统的应用及选择

- - CSDN博客推荐文章
当下,互联网行业发展非常迅猛,分布式文件系统在其中的应用也非常普遍. 一些朋友问起一些相关问题,如:. 搜索引擎类的那些页面文本文件存储,用什么DFS比较好. 海量小图片类的,如taobao里头,好多商家图片,用什么存储. 视频类的,如优酷,用什么DFS. 它只需要能把那些文本文件分块分散到各个节点上进行顺序存储就行了.

jQuery EasyUI1.3.2 comobotree 组件弹出后自动滚动到选择的节点

- - ITeye博客
  jQuery EasyUI1.3.2  comobotree 组件弹出后自动滚动到选择的节点. 在加载完成Easyui JS加载完成后,添加默认事件:弹出后自动滚动到对应的节点. //当combotree弹出显示时自动滚动到对应位置 $.fn.combotree.defaults.onShowPanel = function(){.