改善你的jQuery的25个步骤

1. 从Google Code加载jQuery
Google Code上已经托管了多种JavaScript类库,从Google Code上加载jQuery比直接从你的服务器加载更有优点。它节省了你服务器上的带宽,可以很快的从Google的内容分布网络(CDN)上加载JS类库。更重要的是,若是用户访问那些发布在Google Code上的站点后它会被缓存下来。
这样作颇有意义。有多少站点使用了没有被缓存的相同jQuery副本,而这些很容易作到,引入:javascript

<script type="text/javascript" src=" http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>css

2. 使用备忘单
不只仅是jQuery,不少编程语言也有相似的备忘单,在一张A4的纸上就能够很容易看到每一个函数的用法。幸运的是已经有好心的家伙把jQuery的备忘单作得很完善了:
http://www.gscottolson.com/weblog/2008/01/11/jquery-cheat-sheet/
http://colorcharge.com/jquery/html

3. 整合全部的脚本并缩减它们
不错,这是JavaScript的一个常见技巧。但是一个使用了jQuery的大项目可能使用了不少相关的jQuery插件(本站就使用了easing,localScroll,lightbox,preload),所以它一般是适用的。浏览器不能同时加载JS脚本(大多数状况下),这意味着若是你同一时间加载不少脚本的话,将减缓页面的加载速度。所以,若是每一个页面都要加载这些脚本,你应该考虑在发布以前将这些脚本整合成一个稍大的JS脚本。一些jQuery插件已经最小化了,可是你应该打包你的JS脚本和那些没有缩减过的脚本,这仅须要几秒的时间就能够完成。
就我的而言,我推荐Packer by Dean Edwardsjava

4. 使用Firebug出色的控制台日志工具
若是你尚未安装Firebug,那么你真的应该把它装上。除了许多其它有用的特性(好比容许你检查http传输状况、发现你的CSS问题),它也有极好的日志命令,容许你很容易调试JS脚本。
这里有Firebug全部特性的详细说明
我最喜欢的特性有”console.info“,经过它你能够把信息和变量值输出到控制台上,而没必要使用alert;”console.time”则容许你在一组代码上设置定时器,从而计算出JS脚本运行所花费的时间。这一切都很容易作到:
jquery



console.time('create list'); 
for (i = 0; i < 1000; i++) { 
var myList = $('.myList'); 
myList.append('This is list item ' + i); 

console.timeEnd('create list'); 

5. 经过缓存最小化选择操做
jQuery的选择器棒极了。它们能够在页面上以极其简单的方法找到任何元素,可是在内部它们必须经过大量的步骤才能够实现选择操做,若是你错误的使用它们,那么你可能发现一切都变得至关慢。
若是你一次又一次的选择相同元素(例如在一个循环中),那么你能够一次选择出它并放入内存中,同时你能够在核心内容里操做它。看下面的例子,这里咱们利用循环往UL里添加条目:


for (i = 0; i < 1000; i++) { 
var myList = $('.myList'); 
myList.append('This is list item ' + i); 


这在个人PC上Firefox 3花费了1066毫秒时间(能够设想一下在IE6中的状况!),对JavaScript而言这个操做至关慢。如今让咱们来看看下面的代码,这里咱们仅使用了一次选择操做:


var myList = $('.myList'); 
for (i = 0; i < 1000; i++) { 
myList.append('This is list item ' + i); 


仅仅用了224毫秒,经过移动一行代码就快了将近4倍。

6. 最小化DOM操做
咱们经过减小对DOM的插入操做可让上面的代码运行得更快。DOM的插入操做(像.append(),.prepend(),.after(),.wrap())是至关耗时的,执行这些操做会拖慢程序的运行。
咱们所要作的就是使用字符串拼接来构造一个list项并用一个函数往列表里添加这些项,好比.html()。请看下面的例子:
程序员



var myList = $('#myList'); 
for (i=0; i<1000; i++){ 
myList.append('This is list item ' + i); 


在个人PC上花费了216毫秒,仅仅在1/5秒左右。可是若是咱们使用字符串构造list项,使用下面的HTML方法完成插入操做: 


var myList = $('.myList'); 
var myListItems = ''; 
for (i = 0; i < 1000; i++) { 
myListItems += '<li>This is list item ' + i + '</li>'; 

myList.html(myListItems); 

它耗时185毫秒,尽管没有快不少,可是也提升了31毫秒的时间。
7. 处理DOM插入操做时,将须要的内容包装在一个元素中
嗯,不要问我为何要这样作(我相信一个有至关经验的程序员会给你解释)。
在上面的例子中咱们使用.html()将1000个item项插入到UL中。若是在插入操做以前咱们将这些项包装在UL标签中,而后把完整的UL插入到另外一个DIV标签中,那么咱们实际上仅仅插入一个标签而不是1000个,这看起来要更高效些。请看下面这个例子:


var myList = $('.myList'); 
var myListItems = '<ul>'; 

for (i = 0; i < 1000; i++) { 
myListItems += '<li>This is list item ' + i + '</li>'; 

myListItems += '</ul>'; 
myList.html(myListItems); 

如今所花费的时间仅19毫秒,比咱们以前的第一个例子明显提升了50倍。 
8. 尽量使用ID而不是class
jQuery利用classes进行DOM元素选择操做与经过ID进行选择同样容易,所以与以前相比更自由的使用classes进行元素选择操做颇有吸引力。不过因为jQuery使用浏览器固有的方法(getElementById )进行选择操做,所以利用ID进行选择操做更有优点。有多快呢?让咱们来看看。
我使用前一个例子,修改它以便于咱们建立的每一个LI有一个惟一的class。而后我将遍历之,每次选择一个元素:


// Create our list 
var myList = $('.myList'); 
var myListItems = '<ul>'; 
for (i = 0; i < 1000; i++) { 
myListItems += '<li class="listItem' + i + '">This is a list item</li>'; 

myListItems += '</ul>'; 
myList.html(myListItems); 
// Select each item once 
for (i = 0; i < 1000; i++) { 
var selectedItem = $('.listItem' + i); 


正如所想的,个人浏览器花费了5066毫秒的时间(5秒多)。所以我修改上述代码以使用ID而不是class,而后经过ID进行选择。 


// Create our list 
var myList = $('.myList'); 
var myListItems = '<ul>'; 
for (i = 0; i < 1000; i++) { 
myListItems += '<li id="listItem' + i + '">This is a list item</li>'; 

myListItems += '</ul>'; 
myList.html(myListItems); 
// Select each item once 
for (i = 0; i < 1000; i++) { 
var selectedItem = $('#listItem' + i); 


仅仅耗时61毫秒,几乎快了100倍 

9. 给选择器提供上下文
默认状况下,当你使用相似$('.myDiv')的选择器时将在整个DOM文档查找元素,这有很大的代价。
当执行选择操做时,jQuery函数能够指定第二个参数:jQuery( expression, context )经过给选择器提供一个上下文,那就会在这个context中进行元素查找,而没必要在整个DOM文档中查找元素。
为了解释这个,咱们采用前面的第一段代码。它建立一个有1000项内容的UL,每项都有一个单独的class。
而后遍历之每次选择一项。你应该记得经过class选择全部的1000项item须要耗时5秒多。
web



var selectedItem = $('#listItem' + i); 

而后我给其添加一个上下文,以便于仅在UL中执行选择操做: 


var selectedItem = $('#listItem' + i, $('.myList')); 

因为效率太差,仍耗时3818毫秒的时间,可是经过一个很小的修改仍得到了25%的速度提高。 
10. 正确使用方法链
jQuery最炫的一个特性就是jQuery可以连续的进行方法调用。举例来讲,你想去切换元素的class:


$('myDiv').removeClass('off').addClass('on'); 

若是你像我这样,你可能在前五分钟的jQuery学习就能够更进一步使用它。首先它仍能够跨行操做(jQuery是JavaScript) ,这意味着你可以写出下面这样工整的代码: 


$('#mypanel') 
.find('TABLE .firstCol') 
.removeClass('.firstCol') 
.css('background' : 'red') 
.append('<span>This cell is now red</span>'); 

使用链表的习惯将有助于你减小选择器的使用。然而能够更深刻使用之,你想在一个元素上执行好几个函数,可是以某种方式改变了操做的元素: 


$('#myTable').find('.firstColumn').css('background','red'); 

咱们选择了一个表格,在其中找到class为”firstColumn”的单元格,而后使之背景变为红色。 
如今咱们但愿将全部class为”lastColumn”的单元格背景设为蓝色。由于咱们已经使用了find()函数过滤出class不为”firstColumn”的全部单元格,所以咱们须要再一次对表格使用选择操做,咱们难道不能连续进行方法调用吗?幸运的是jQuery提供了end()函数,这将匹配的元素列表变为前一次状态以便于你能够执行方法链表: 


$('#myTable') 
.find('.firstColumn') 
.css('background','red') 
.end() 
.find('.lastColumn') 
.css('background','blue'); 

写一个可以进行方法链式调用的自定义jQuery函数也很容易。你所作的就是要写个能修改元素并返回元素的函数。 


$.fn.makeRed = function() { 
return $(this).css('background', 'red'); 

$('#myTable').find('.firstColumn').makeRed().append('hello'); 

它很简单吧! 

11. 学会正确使用效果
在我刚开始使用jQuery的时候,就很喜欢这一点:它能够很容易使用预约义好的各类动画效果,像slideDown()和fadeIn()之类的。因为jQuery提供的animate()方法十分易用和强大,咱们很容易深刻使用它。事实上,在jQuery源代码中很多方法就是经过animate()函数来实现效果的。
ajax



slideDown: function(speed,callback){ 
return this.animate({height: "show"}, speed, callback); 
}, 

fadeIn: function(speed, callback){ 
return this.animate({opacity: "show"}, speed, callback); 


animate()方法仅仅做用在CSS上,根据数值平滑的进行转换。所以你可以改变宽度、高度、透明度、背景色、top、left、margin、颜色、字体大小以及任何你想要的。 
给菜单项添加高度变化的效果是很容易作到的: 


$('#myList li').mouseover(function() { 
$(this).animate({"height": 100}, "slow"); 
}); 

不像其余的jQuery函数,动画效果自动的排进队列,所以若是在第一个特效完成以后你想运行第二个特效,须要两次调用animate方法: 


$('#myBox').mouseover(function() { 
$(this).animate({ "width": 200 }, "slow"); 
$(this).animate({"height": 200}, "slow"); 
}); 

若是你想动画效果同时发生,那么须要将全部的styles做为一个参数对象传入方法中: 


$('#myBox').mouseover(function() { 
$(this).animate({ "width": 200, "height": 200 }, "slow"); 
}); 

你可以给值是数字的属性添加动画效果。你也能够下载插件帮助你给非数字值的属性添加动画效果,像 colors and background colors  

12. 了解事件代理
与以前相比,jQuery可以更容易得向DOM元素无缝添加事件。这是很棒的特性,然而向元素添加太多的事件是效率不好的。在不少状况下事件代理容许你用少许的事件实现一样的目的。最好的解释方法就是使用实例:
express



$('#myTable TD').click(function(){ 
$(this).css('background', 'red'); 
}); 

当咱们点击表格中的单元格时,上面的代码将使全部单元格背景变为红色。比方说,你有一个10列、50行的网格,那么就会绑定上500个事件。嗯,这时就是事件代理出场的时候了: 


$('#myTable').click(function(e) { 
var clicked = $(e.target); 
clicked.css('background', 'red'); 
}); 

e'包含了事件的信息,包括了实际接收到click事件的目标元素。咱们所要作的就是检查是哪一个单元格被点击了。至关的巧妙! 
事件代理带来了另一个好处。正常状况下,在你往一个元素集合绑定一个事件,该事件仅仅只是绑定到这些集合元素上。若是你向DOM中添加了新的元素,尽管这些新元素被选择器所匹配,可是这些新元素并不会绑定上事件处理(你赞成个人观点吗?),所以不会有事件发生。 
当使用事件代理时,你可以在事件被DOM绑定后仍然能够添加多个被匹配的元素到其中,而它们一样可以正常工做。
13. 利用classes存储状态
这是在html中存储信息最基本的方法。jQuery擅长基于classes进行元素的操做,所以若是你须要存储元素的状态信息,为何不试试使用额外的class来存储它呢?
这里有一个例子。咱们想建立一个展开的菜单。当你点击按钮时,咱们但愿经过slideDown()和slideUp()进行菜单的展开与收缩。请看下面的HTML:


<div class="menuItem expanded"> 
<div class="button"> 
click me 
</div> 
<div class="panel"> 
<ul> 
<li>Menu item 1</li> 
<li>Menu item 2</li> 
<li>Menu item 3</li> 
</ul> 
</div> 
</div> 

很是的简单!咱们仅仅向包装器DIV添加一个额外的class,它只是告诉咱们item项的状态。所以在按钮点击以后咱们所须要的只是click事件处理,这会执行相应的slideUp()和slideDown()方法。 


$('.button').click(function() { 

var menuItem = $(this).parent(); 
var panel = menuItem.find('.panel'); 

if (menuItem.hasClass("expanded")) { 
menuItem.removeClass('expanded').addClass('collapsed'); 
panel.slideUp(); 

else if (menuItem.hasClass("collapsed")) { 
menuItem.removeClass('collapsed').addClass('expanded'); 
panel.slideDown(); 

}); 


这是很简单的一个例子,不过你能够给一个元素或HTML片段添加额外的classes以存储全部种类的信息。 
然而,除了在简单的状况以外咱们更应该使用下面这个技巧。 
14. 更好的方法是利用jQuery内置的data()方法存储状态
因为某些缘由,这方面没有很好的文档能够参考。jQuery提供了内置的data()方法,与DOM元素不一样的是,它能够用来存储key/value类型的数据。数据的存储是很容易的:
复制代码代码以下:

$('#myDiv').data('currentState', 'off'); 

咱们修改上一个例子的代码,以便于咱们可使用相同的HTML内容(除了没有”expanded”类)并使用data()函数来进行状态的存储: 


$('.button').click(function() { 

var menuItem = $(this).parent(); 
var panel = menuItem.find('.panel'); 

if (menuItem.data('collapsed')) { 
menuItem.data('collapsed', false); 
panel.slideDown(); 

else { 
menuItem.data('collapsed', true); 
panel.slideUp(); 

}); 

我相信你也会赞同这种方法的使用的确更加的精巧,对于data()和removeData()的更多信息,请查看 jQuery internals  
15. 写你本身的选择器
jQuery有许多内置的选择器用以经过ID、class、标签、属性以及其余元素进行选择操做。然而当你须要基于其它一些内容进行元素选择而jQuery却没有提供该选择器时,你能作什么呢?
嗯,一个解决方案多是从一开始就给元素添加上classes,从而利用这些classes进行元素的选择操做。然而这被证实很难对jQuery扩展出新的选择器。
最好的解释方法就是使用实例:


$.extend($.expr[':'], { 
over100pixels: function(a) { 
return $(a).height() > 100; 

}); 

$('.box:over100pixels').click(function() { 
alert('The element you clicked is over 100 pixels high'); 
}); 

代码的前一部分建立一个自定义的选择器,它能够找出全部长度超过100px的元素。接下来的代码仅仅是将click事件绑定到使用该选择器查找出来的那些元素上。 
这里我不作更具体的讲解,可是你能设想一下它有多么的强大!若是你在google上搜索”custom jquery selector”,你会看到有不少这方面的例子。 

16. 精简你的HTML并在页面加载后修改它
这个标题可能没有多大意思,可是这个技巧可能理顺你的代码、减少代码体积和页面的下载时间、有助优化你的搜索引擎。请看下面的例子:
编程



<div class="fieldOuter"> 
<div class="inner"> 
<div class="field">This is field number 1</div> 
</div> 
<div class="errorBar"> 
<div class="icon"><img src="icon.png" alt="icon" /></div> 
<div class="message"><span>This is an error message</span></div> 
</div> 
</div> 
<div class="fieldOuter"> 
<div class="inner"> 
<div class="field">This is field number 2</div> 
</div> 
<div class="errorBar"> 
<div class="icon"><img src="icon.png" alt="icon" /></div> 
<div class="message"><span>This is an error message</span></div> 
</div> 
</div> 

上面是一个HTML的具体例子,为了解释目的作了少许修改。我相信你也会认为这段代码至关的丑陋。若是相似代码很长的话,你最终会造成一个至关长且丑陋的页面。所以你能够像下面这样处理它: 


<div class="field">This is field 1</div> 
<div class="field">This is field 2</div> 
<div class="field">This is field 3</div> 
<div class="field">This is field 4</div> 
<div class="field">This is field 5</div> 

全部你要作的就是在页面加载完成以后经过jQuery的操做将丑陋的HTML添加回去: 


$(document).ready(function() { 
$('.field').before('<div class="fieldOuter"><div class="inner">'); 
$('.field').after('</div><div class="errorBar"><div class="icon"> 
<img src="icon.png" alt="icon" /></div><div class="message"> 
<span>This is an error message</span></div></div></div>'); 
}); 

这样作并不老是可取的,在页面加载后的一瞬间你将会看到页面的闪动,可是在特定状况下你有不少重复的HTML内容,这时经过这个方法你能够显著的减少页面代码体积,减小无关且重复的标记能使你的SEO从中受益。 
17. 为了速度和SEO方面的考虑,延迟加载内容
另外还有一个方法能够提高页面加载速度,理顺Spiders搜索的HTML内容,经过在页面加载以后使用AJAX请求晚加载其余内容,这样用户就能够立刻开始浏览,让Spider看到你想要它们进行索引的内容。
咱们已经在本身的网站上使用了这个技术。本页面上部的紫色按钮会弹出三个表格,方位与Google地图,这会使咱们页面大小增长两倍。所以咱们仅须要把这些HTML内容放入一个静态页面中,在页面加载完成以后经过load()函数加载它:


$('#forms').load('content/headerForms.html', function() { 
// Code here runs once the content has loaded 
// Put all your event handlers etc. here. 
}); 

我不会在页面上随处使用这个技巧。对此,你必须权衡考虑。你须要有额外的页面请求,并且页面上的部份内容不能当即呈现给用户,可是正确的使用这个技巧对优化会颇有帮助。 
18. 使用jQuery提供的工具函数
jQuery不只仅有闪光的效果。jQuery做者也提供了一些至关实用的方法,这填补了JacaScript的一些缺陷。
http://docs.jquery.com/Utilities
尤为,提供一些常见的数组函数的浏览器支持是一个补丁。jQuery提供了迭代、过滤、克隆、合并和从数组中去除重复项的方法。
其余经常使用的函数包括获得下拉框中的选择项。用传统的JavaScript方法,你就必须使用getElementById获得<select>元素,而后经过遍历它的子元素找出被选中的元素。而jQuery提供了至关容易使用的方法:

$('#selectList').val();

花时间浏览官方网站上的jQuery文档与一些不经常使用的方法上是很值得的。 
19. 使用noConflict重命名jQuery对象
大多数JavaScript框架都使用$符号做为缩写,当在同一个页面使用多个JS框架时,页面很容易发生冲突。幸运的是有一个简单的方法。noConflict()函数交回$的控制权并容许你设置成本身的变量名:


$('#selectList').val(); 

20. 如何得知图片已加载完毕
这也一个没有很好文档说明的问题(至少在我查找时没看到),可是在建立照片库、旋转灯笼效果等方面,它是至关常见的需求。而这在jQuery中很容易实现。
全部你要作的就是在IMG上使用.load()方法,在其中添加一个回调函数。下面的例子改变了一个图片src的属性同事附加上一个简单的load函数:


$('#myImage').attr('src', 'image.jpg').load(function() { 
alert('Image Loaded'); 
}); 

你应该能够发现一旦图片加载完毕就会弹出一个alert。 
21. 老是使用最新版本
jQuery仍在不断的更新,它的做者John Resig一直在寻找提升jQuery性能的方法。jQuery当前的版本是1.3.2,John已经宣称他正在写一个新的选择器引擎Sizzle,这可能会显著的提升选择器性能(在Firefox中提高了4倍),所以咱们应当保持最新版本。

22. 如何检查元素是否存在
你没必要检查元素是否在页面上存在就可使用它,由于若是没有在DOM中找到合适的元素,jQuery什么也不会作。但是当咱们须要检查元素是否被选择了,或是有多少项被选择了,你可使用length属性:



if ($('#myDiv).length) { 
// your code 
}

简单之极。 
23. 给你的HTML属性增长JS类
我是从Karl Swedberg那学到这个技巧,过去学习jQuery时一直在看他的书。
他最近在我之前的文章留下了对该用法的评论,基本原则以下示之。
首先,在jQuery加载以后你可使用方法将”JS”类添加到HTML标签中:

$('HTML').addClass('JS');

由于这仅仅发生在javascript有效的时候,若是用户打开JavaScript开关,那么你可使用它给元素添加上CSS风格: 

.JS #myDiv{display:none;}


所以,这意味着在JavaScript打开时咱们能够隐藏内容,而后在须要时使用jQuery显示这些内容(好比在用户点击时收缩或展开内容),同时在关闭JavaScript(以及搜索Spiders)时会看到全部内容。我将在晚些时候使用这个技巧。
能够在这里看到 他的全部文章 。 
24. 返回'false'以防止默认行为
这是很明显的,也可能不是。若是你有这样的习惯:
复制代码代码以下:

<a href="#" class="popup">Click me!</a>

而后添加上以下的事件处理: 


$('popup').click(function(){ 
// Launch popup code 
}); 


你在长页面使用上述方法时,它可能能够正常工做。有些时候你会注意到在点击连接后锚点会跳转到页面上部。 
全部你要作的就是阻止它的默认行为,或者实际上你能够把”return false;”添加到任何事件的默认行为上。像这样: 
复制代码代码以下:

$('popup').click(function(){ 
// Launch popup code 
return false; 
}); 

25. ready事件的简写
一个小技巧可是经过使用$(document).ready()的简写,你能够少输入几个字符。
取代:

代码以下:

$(document).ready(function (){ 
// your code 
});

你能够简写成: 

$(function (){  // your code  }); 
相关文章
相关标签/搜索