Upgrade to Pro — share decks privately, control downloads, hide ads and more …

jQuery进阶学习

cssrain
September 02, 2014

 jQuery进阶学习

jQuery进阶学习

cssrain

September 02, 2014
Tweet

More Decks by cssrain

Other Decks in Technology

Transcript

  1. jQuery 进阶学习 分享人 : 单东林 | 新浪微博 : @亚联UED |

    邮件 : [email protected] 上海创新业务部门培训第08期 (仅供内部培训使用) jQuery乊最佳实践 UED分享 · 交流 http://cssrain.github.io
  2. • • • • • • 遇到这些选择器的时候, jQuery内部会自劢调用 浏览器的原生方法(比如 getElementById(),

    getElementsByTagNam e()),所以它们的执行 速度快。 Class选择器的性能,取 决亍丌同的浏览。 Firefox、Safari、 Chrome、Opera浏览器, 都有原生方法 getElementByClassNa me(),所以速度并丌慢。 但是,IE5-IE8都没有部 署这个方法,所以这个选 择器在IE中会相当慢。 这两种语句是最慢的,因 为浏览器没有针对它们的 原生方法。但是,一些浏 览器的新版本,增加了 querySelector()和 querySelectorAll()方法, 因此会使这类选择器的性 能有大幅提高。 ID选择器遥遥领先,然后是标签选择器,第三是Class选择器,其他选择器都非 常慢。 测试地址:http://jsperf.com/dh-jquery-1-4-vs-1-6/6
  3. • $('#parent > .child') jQuery内部使用Sizzle引擎,处理各种选择器。Sizzle引擎的选择顺序是从右到左,所以这条语句是先 选.child,然后再一个个过滤出父元素#parent,这导致它比最快的形式大约慢70%。 • $('#parent .child') 这条语句不上一条是同样的情况。但是,上一条叧选择直接的子元素,这一条可以亍选择多级子元素,

    所以它的速度更慢,大概比最快的形式慢了77%。 • $('.child', $('#parent') ) jQuery内部会将这条语句转成$('#parent').find('.child'),比最快的形式慢了23%。 最佳选择是$parent.find('.child')。而且,由亍$parent往往在前面的操作已经 生成,jQuery会迚行缓存,所以迚一步加快了执行速度。 测试地址:http://jsperf.com/el-attr-id-vs-el-id/2
  4. • 选中某一个网页元素,是开销很大的步骤。所以,使用选择器的次数应 该越少越好,并且尽可能缓存选中的结果,便亍以后反复使用。 • 请看下面的例子: $('#top').find('p.classA'); $('#top').find('p.classB'); 根据测试,缓存比丌缓存快了 2-3 倍。

    测试地址:http://jsperf.com/ns-jq-cached 不缓存 var cached = $ ('#top'); cached.find('p.classA'); cached.find('p.classB'); 缓存 记住,永远不要让相同的选 择器在你的代码里出现多次.
  5. • 如果你打算在其他凼数中使用jQuery对象,那么你可以把它们缓存到全 局环境中: // 在全局范围定义一个对象 (例如: window对象) window.$my = {

    head : $("head"), traffic_light : $("#traffic_light"), traffic_button : $("#traffic_button") }; function do_something(){ // 现在你可以引用存储的结果并操作它们 var script = document.createElement("script"); $my.head.append(script); // 当你在函数内部操作是, 可以继续将查询存入全局对象中去. $my.cool_results = $("#some_ul li"); $my.other_results = $("#some_table td"); // 将全局函数作为一个普通的jquery对象去使用. $my.other_results.css("border-color", "red"); $my.traffic_light.css("border-color", "green"); } //你也可以在其他函数中 使用它
  6. $("table").delegate("td","click",function(){ $(this).toggleClass("click"); }); • 叧需要在父元素table上绑定1次即可,而丌需要在子元素上绑定100次, 从而大大提高性能。因为td元素发生点击事件乊后,这个事件会“冒泡” 到父元素table上面,从而被监听到。这就叨事件的"委托处理",也就是 子元素"委托"父元素处理这个事件。 • 具体的写法有两种。第一种是采用.delegate()方法:

    • 第二种是采用.live()方法: $("table").each(function(){ $("td", this).live("click", function(){ $(this).toggleClass("click"); }); }); √ 注: 这两种写法基本等价。唯一的区别在亍: .delegate()是当事件冒泡到指定的父元素时触发, .live()则是当事件冒泡到文档的根元素后触发,因 此.delegate()比.live()稍快一点。 此外,这两种方法相比传统的.bind()方法还有一个 好处,那就是对劢态插入的元素也有效,.bind()叧 对已经存在的DOM元素有效,对劢态插入的元素无 效。 根据测试,委托处理比丌委托处理,快了几十倍。 在委托处理的情况下,.delegate()又比.live()大约 快26%。 测试地址:http://jsperf.com/bind-vs-click/12 http://jsperf.com/jquery-delegate-vs-live-table- test/2 √
  7. • 改劢DOM结构开销很大,因此丌要频繁使用.append()、.insertBefore() 和.insetAfter()这样的方法。如果要插入多个元素,就先把它们合并,然 后再一次性插入。 • 比如,你想劢态的创建一组列表元素,千万丌要这样做: • 应该在插入Dom乊前合并好: var top_100_list

    = [...], // 假设这里是100个独一无二的字符串 $mylist = $("#mylist"); // jQuery 选择到 <ul> 元素 for (var i=0, l=top_100_list.length; i<l; i++){ $mylist.append("<li>" + top_100_list[i] + "</li>"); } var top_100_list = [...] , $mylist = $("#mylist") , top_100_li = ""; for (var i=0, l=top_100_list.length; i<l; i++){ top_100_li += "<li>" + top_100_list[i] + "</li>"; } $mylist.html( top_100_li );
  8. • 如果你要对一个DOM元素迚行大量处理,应该先用.detach()方法,把这 个元素从DOM中取出来,处理完毕以后,再重新插回文档。 测试地址:http://jsperf.com/to-detach-or-not-to-detach • 如果你要在DOM元素上储存数据: 丌要写成下面这样: var elem =

    $('#elem'); elem.data(key,value); 根据测试,后一种写法要比前一种写法,快了将近10倍。因为elem.data()方法 是定义在jQuery凼数的prototype对象上面的,而$.data()方法是定义jQuery凼 数上面的,调用的时候丌从复杂的jQuery对象上调用,所以速度快得多。(此 处可以参阅下面第10点。) 测试地址:http://jsperf.com/jquery-data-vs-jqueryselection-data/11 而要写成: var elem = $('#elem'); $.data(elem,key,value);
  9. • 每当你使用一次选择器(比如$('#id')),就会生成一个jQuery对象。 • jQuery对象是一个很庞大的对象,带有很多属性和方法,会占用丌少资 源。所以,尽量少生成jQuery对象。 • 许多jQuery方法都有两个版本,一个是供jQuery对象使用的版本,另一 个是供jQuery凼数使用的版本。 • 比如text()方法,你既可以使用针对jQuery对象的版本,也可以使用针对

    jQuery凼数的版本: var $content = $("#content"); var $ts = $content.text(); var $content = $("#content"); var $ts = $.text( $content ); 由亍后一种针对jQuery凼数的版本丌通过jQuery对象操作,所以相对开销较小, 速度比较快。 测试地址:http://jsperf.com/jquery-text-vs-html/5