天天看点

提高jQuery的性能

1,从google code加载jQuery

google

code已经集合了几个JavaScript库,我们可以从那里加载这些库而不必通过自己的服务器加载。这样的好处是节省带宽,如果用户访问过同样加载了这些库的网站后,JavaScript库会缓存在用户端,提高加载速度。

<a href="http://www.lzby.net/boho/blog/?p=391#">PLAIN TEXT</a>

JavaScript:

&lt;script

src="http://www.google.com/jsapi"&gt;&lt;/script&gt;

&lt;script type="text/javascript"&gt;&lt;!--

// 加载jQuery

google.load("jquery", "1.2.6");

google.setOnLoadCallback(function() {

    // 自己的代码...

});

// --&gt;&lt;/script&gt;

也可以直接声明一个指向:

src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"

type="text/javascript"&gt;&lt;/script&gt;  

2,将匹配选择器元素对象保存在变量中。

尤其在循环体里,下面的做法影响运行效率:

for (i = 0; i

&amp;lt;1000; i++) {

var myList = $('.myList');

myList.append('This is list item ' + i);

}

上面的代码在我的机器上耗时1066毫秒。除非我疯了才会将选择器表达示放在循环体里。应该这样做:

 myList.append('This is list item

' + i);

上面的代码耗时只有224毫秒。想要更快还可以这样做:

var myListItems = '&lt;ul&gt;';

myListItems+='This is list item ' + i;

myListItems+='&lt;/ul&gt;';

myList.html(myListItems);

也就是说尽量减少直接对DOM进行操作,还有直接填充内容比插入内容要快。上面的代码只需185毫秒,尽管不算很明显,但至少显示出可优化的空间。

3,如果可以,选择器尽量选取ID属性。

4,为选择器设定一个范围。

如果使用$('.myDiv')这样的选择器表达示,毫无疑问的是对整个DOM进行了一次遍历,然后返回匹配的元素对象。然而如果为它设定一个范围将会提高运行效率。jQuery(expression,

context)函数有两个参数,第一个是表达示,第二个就是范围。指定了范围参数,选择器只会在这个范围内进行选取。例如:

var selectedItem = $('#listItem' +

i, $('.myList'));

5,正常运用连接语句

jQuery最cool的一种用法就是将方法和调用连接起来,例如切换某元素的class属性:

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

如果要连接的方法调用很多,jQuery同样和JavaScript一样可以将语句分行书写:

$('#mypanel')

.find('TABLE

.firstCol')

.removeClass('.firstCol')

.css('background'

: 'red')

.append('&lt;span&gt;This

cell is now red&lt;/span&gt;');

如果养成良好的连接语句的习惯,有助于减入选择器的使用。上面的代码只进行了一次选择器操作,然而却干完了4件事。很难想像将它分开进行4次操作会消耗多少资源,而且书写代码量也少了很多。所以为什么不这么做呢?

接下来再看看,要选取表格中的class='firstColumn'的单元格,并设它的背景色为red:

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

很显然,上面的代码进行了两次选择器操作。而.css()调用只会作用到表格中class='firstColumn'的单元格里。这时我们又需要对同一表格中class='lastColumn'的单元格进行操作该如何做呢?看起来不能将它们连在一起写,难道要重新写一句吗?当然不用:

$('#myTable')

.find('.firstColumn')

.css('background','red')

.end()

.find('.lastColumn')

.css('background','blue');

这里用到了.end(),作用是如果连接了多个选择器,将返回到最初的一个选择器中。也就是将$('#myTable').find('.firstColumn')返回到$('#myTable'),然后再$('#myTable').find('.lastColumn')。这样就解决了刚才说的问题。

同样支持自定义的jQuery函数:

$.fn.makeRed =

function() {

return $(this).css('background',

'red');

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

6,学会在适当的时候使用动画

查看一下jQuery的源代码会发现jQuery库中很强大的slideDown()和fadeIn()都是调用jQuery本身的animate()方法:

slideDown:

function(speed,callback){

return this.animate({height: "show"},

speed, callback);

},

fadeIn:

function(speed, callback){

return this.animate({opacity: "show"},

animate()方法采用从一个CSS样式到另一个CSS样式的过渡实现动画效果。因此可以为元素定义背景色、长度、宽度和透明试等等形式的动画效果。

$('#myList

li').mouseover(function() {

$(this).animate({"height": 100}, "slow");

上面的代码实现鼠标移到元素上时,高度渐渐变成100像素。

有别于jQuery其它的函数方法,animate()支持自动队列。一旦一个动画完成后又会进行第二个动画,这并不需要进行回调处理:

$('#myBox').mouseover(function() {

$(this).animate({ "width": 200

}, "slow");

$(this).animate({"height": 200}, "slow");

animate()还支持多个css同时放置。例如:

$(this).animate({ "width": 200,

"height": 200 }, "slow");

7,事件委托

jQuery比以往更重视元素事件委托,这更能体现unobtrusively(无侵入)原则。在元素上添加太多的事件会降低效率,也不便书写和调试。而事件委托能用较少的代码完成同样的功能。

$('#myTable

TD').click(function(){

$(this).css('background',

因为就不需要在DOM内添加onClick事件,从而使DOM很简洁。假设有一个表格,10列50行,每点击一个单元格后,该单元格背景变red。是不是要进行500次事件委托呢?很明显是不需要:

$('#myTable').click(function(e) {

var clicked = $(e.target);

clicked.css('background',

'e'返回实际响应点击的元素,因此可以取得被点击的目标元素。看上去简洁许多。

8,书写自己的选择器

必要的时候,可以创建自己的选择器。当jQuery内置的选择器无法更有效地完成选取操作时,自己创建的选择器可以对内置选择器进行扩展。

$.extend($.expr[':'], {

over100pixels: function(a) {

return $(a).height()&amp;gt; 100;

$('.box:over100pixels').click(function() {

alert('The element you

clicked is over 100 pixels high');

上面代码的第一部分是创建一个自定义的选择器,即返回所有高度超过100像素的元素。代码的第二部分只是将匹配的元素进行事件绑定,匹配元素被点击时,弹出一个对话框。这里只是说明选择器是可扩展的,我将陆续发布有关扩展jQuery扩展的post。

9,利用noconflict来重命名jQuery对象

大多数的JavaScript框架库使用$标记符,如果在同一页里使用了不同的JavaScript框架,而且都用$做标记符,必定会引志冲突。好在jQuery提供了noConflict()方法来重命名标记符。例如:

var $j = jQuery.noConflict();

$j('#myDiv').hide();

这时$符号变成了$j。只要出现$j的标记符就是使用jQuery库。

10,判断画片加载完毕

这个问题好像没有答案。怎样去判断一个图片真正加载完毕了呢?用.load()方法吧。

$('#myImage').attr('src', 'image.jpg').load(function() {

alert('Image

Loaded');

运行后如果图片加载完毕了,会弹出对话框。这是使用了回调函数。

11,如果检查DOM中的某元素是否存在

如果要对某元素进行操作,并不需要先去检查该元素时否存在于DOM中。因为jQuery的方法或函数对那些并不存在的元素根本不会进行任何操作。但如果需要知道是否已有选定或选定的数量时,可以用length属性:

if ($('#myDiv).length) {

12,简化的$(document).ready

通常需要这样写:

$(document).ready(function (){

// ...

其实还可以这样写:

$(function (){

});  

继续阅读