当前位置: 代码迷 >> Web前端 >> jQuery:告发jQuery的隐藏功能
  详细解决方案

jQuery:告发jQuery的隐藏功能

热度:297   发布时间:2012-11-23 00:03:43.0
jQuery:揭露jQuery的隐藏功能

jQuery并不像他表面显示的那样,只有那些额定的方法供我们使用。其他在他库的代码内有着很多很酷很便捷的潜在方法,等待被我们发现。在本文中,我将带领你去领略一些我在jQuery库中发现的那些不怎么常见的方法。

1.理解jQuery方法:

当你调用jQuery方法时会发生什么呢?看看jQuery的方法体,非常地简单。

1
2
3
4
jQuery = function (selector, context) {
    // The jQuery object is actually just the init constructor 'enhanced'
    return new jQuery.fn.init(selector, context);
};

在表层的代码之下,jQuery方法(通常称之为“包装”方法)将返回一个实例化后的jQuery对象,即’jQuery.fn.init’构造函数的一个实例。

理解了这一点非常有用,当我们每次调用jQuery方法时,都会返回一个带有一组属性的完全独立的对象。而jQuery的聪明之处在于返回的这个对象是以数组的方式返回的。该对象中的所有元素(通称”集合“)都是由一个数字索引所指向,就像数组中的下标一样。而且jQuery还返回了一个对象的length属性,就像数组中的长度一样。这种思想给jQuery方法提供了无限的想象空间。比如,我们可以从’Array.prototype’中借用一些功能性方法。jQuery中的slice方法就是一个典型的例子:

1
2
3
4
5
6
7
8
9
10
/* ... jQuery.fn.extend({ ... */
slice: function() {
    return this.pushStack(
        Array.prototype.slice.apply( this, arguments ),
        "slice",
        Array.prototype.slice.call(<wbr>arguments).join(",")
    );
},
/* ... */
</wbr>

在该slice方法不管this是否是一个真实的数组,它和其他的元素会和睦地相处,因为有着”length“这么一个属性。

jQuery中还有一些其他有趣的属性,比如”selector”―选择器,”context”―-上下文等。大部分的时候,只需给jQuery方法传递对象参数即可:

1
2
var jqObject = jQuery('a');
jqObject.selector; // => "a"

一个重要的提示是,jQuery有时会返回一个全新的对象供你使用。比如你试图通过执行一段代码来改变一个集合,如”parent()”方法,但是此时jQuery将不会修改当前的对象,它会返回给你一个全新的对象。

1
2
3
4
var originalObject = jQuery('a');
var anotherObject = originalObject.parents();
?
originalObject === anotherObject; // => false

?

所有试图改变集合的方法都会返回一个新的jQuery对象,你可以通过”.end()”方法或”.prevObject”属性来访问之前的那个对象。

2.面包、奶油元素的建立:

jQuery创建DOM的能力,是其核心功能之一。jQuery1.4新版本带来了一个全新的便捷地创建DOM对象的方法,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var myDiv = jQuery('<div />', {
    id: 'my-new-element',
    class: 'foo',
    css: {
        color: 'red',
        backgrondColor: '#FFF',
        border: '1px solid #CCC'
    },
    click: function() {
        alert('Clicked!');
    },
    html: jQuery('<a />', {
        href: '#',
        click: function() {
            // do something
            return false;
        }
    })
});

在1.4版本中,当你创建一个元素对象时,可以再传入第二参数,该第二参宿可以作为该元素对象的属性设置,也可以理解会调用了.attr()方法。当然,jQuery会自行匹配传入的参数们,如’click’对应了jQuery库中的.click方法,以及’css’、’html’分别对应了jQuery库中的.css()、.html()方法,等等…

3.序列化表单中的input元素:

jQuery提供了一个方法可以将1个或多个表单中的所有input元素进行序列化,这在Ajax提交数据时非常有用。其实该方法在jQuery库中已经存在很长的时间了,但一直很少谈及,所以很多的程序员都忽略了它。通过jQuery中的Ajax方法提交整个表单将变得非常简单。

1
2
3
4
var myForm = $('#my-form');
jQuery.post('submit.php', myForm.serialize(), function(){
    alert('Data has been sent!');
});

jQuery同样也通过了一个’serializeArray’方法,他通常用在多个form表单存在,需要自行收集数据的情况。在jQuery的命名空间下有一个’param’辅助方法可以将一个数组对象处理后返回成一个查询字符串。

1
2
3
4
5
6
7
8
var data = {
    name: 'Joe',
    age: 44,
    profession: 'Web Developer'
};
?
jQuery.param(data); // => "name=Joe&age=44&profession=<wbr>Web+Developer"
</wbr>

?

4.任何元素都可以动画方式展现:

jQuery中的’animate’方法也许是最灵活的jQuery的方法。它可以用几乎任何东西来制作动画,而不仅仅是CSS属性,或者是DOM元素。通常会这样使用’动画’:

1
2
3
4
jQuery('#box').animate({
    left: 300,
    top: 300
});

当您给.animate()方法指定一个属性时(例如’top’),jQuery会检查你是否是想通过某个css属性来控制动画风格。首先jQuery会检查css样式中是否存在该top属性,若不存在,则jQuery会自行地给对应元素加上该属性。下面是一个例子:

1
2
3
4
jQuery('#box').animate({
    top: 123,
    foo: 456
});

上面的代码中’top’是一个可用的css属性,则jQuery就会改变’element.style.top’,但是’foo’不是一个可用的css属性,所以jQuery将只更新’element.foo’。

我们可以利用这个优点来实现一些有趣的效果。比方说,例如,您要在一个画布上使一个正方形动画起来。首先让我们定义一个简单的构造和一个在每一步都会调用的’drwa’的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function Square(cnvs, width, height, color) {
?
    this.x = 0;
    this.y = 0;
    this.width = width;
    this.height = height;
    this.color = color;
?
    this.cHeight = cnvs.height;
    this.cWidth = cnvs.width;
    this.cntxt = cnvs.getContext('2d');
?
}
?
Square.prototype.draw = function() {
?
    this.cntxt.clearRect(0, 0, this.cWidth, this.cHeight);
    this.cntxt.fillStyle = this.color;
    this.cntxt.fillRect(this.x, this.y, this.width, this.height);
?
};

通过jQuery方法创建一个canvas画布元素(需要html5支持),再实例化一个正方形对象,通过调用.animate()方法在动画的每一步过程中调用.draw()方法,这样就可以轻易地使该正方形动画起来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Create a <canvas /> element
var canvas = $('<canvas />').appendTo('body'<wbr>)[0];
canvas.height = 400;
canvas.width = 600;
?
// Instantiate Square
var square = new Square(canvas, 70, 70, 'rgb(255,0,0)');
?
jQuery(square).animate({
    x: 300,
    y: 200
}, {
    // 'draw' should be called on every step
    // of the animation:
    step: jQuery.proxy(square, 'draw'),
    duration: 1000
});
</wbr>

?

这是一个非常简单的效果,但它清楚地表明了jQuery的无限可能性。你可以通过下面的链接看到具体的效果(需要浏览器支持html5):Demo

5.jQuery.ajax方法返回XHR对象:

jQuery的 Ajax方法是一个多功能的方法,它包含了’jQuery.ajax’, ‘jQuery.get’, ‘jQuery.post’等多个方法,这些方法在调用后都会返回一个’XMLHttpRequest’ 对象,从而来实现请求完成后的后续操作。如:

1
2
3
4
5
6
7
8
9
10
11
12
13
var curRequest;
?
jQuery('button.makeRequest').click(function(){
    curRequest = jQuery.get('foo.php', function(response){
        alert('Data: ' + response.responseText);
    });
});
?
jQuery('button.cancelRequest').click(function(){
    if (curRequest) {
        curRequest.abort(); // abort() is a method of XMLHttpRequest
    }
});

上面的代码中当我们点击’makeRequest’按钮时,Ajax请求将会被触发。而当我们点击’cancelRequest’按钮时,该请求则会被取消。

另一个潜在的用途是同步请求:

1
2
3
4
5
6
var myRequest = jQuery.ajax({
    url: 'foo.txt',
    async: false
});
?
console.log(myRequest.responseText);

?

请多的资料可以阅读‘XMLHttpRequest’,也可以阅读Ajax的API文档jQuery’s Ajax utilities

6.自定义队列:

jQuery的有一个内置的队列机制,一般都是有.animate等动画方法使用的(如:.fadeOut()、.fadeIn()等,实质都是有.animate()方法实现)。这种队列机制可以用一个简单的动画就可以说明:

1
2
3
4
5
jQuery('a').hover(function(){
    jQuery(this).animate({paddingLeft:'+=15px'});
}, function(){
    jQuery(this).animate({paddingLeft:'-=15px'});
});

快速地在一个链接标记上鼠标移入、移出,当再次移入时,会导致动画的效果反复执行。不信你可以到这里试试:Demo

‘queue’方法和大家熟知的’each’方法比较相似,你通过给方法传递一个函数参数,则该函数将被匹配集合中的每个元素所调用:

1
2
3
jQuery('a').queue(function(){
    jQuery(this).addClass('all-done').dequeue();
});

给’queue’方法只传入一个函数参数的话会导致该函数被添加到默认的’fx’队列中。若刚好该队列会被jQuery中的所有动画对象所调用,那么只有等前面的这些对象都调用后,才会轮到自己。
鉴于该点,在上面的代码中我给对象添加了一个名为’all-done’的class,根据协议,这个class只有在当前所有的动画都执行完成后才会添加。在代码中我们也调用了.dequeue()方法。这一点很重要,它将使jQuery的继续进行队列。jQuery1.4版本提供了另一个可以继续队列的方法nextItemInQueue(),它可以用来取代调用.dequeue()方法。它的调用只需将第一个参数传递给方法即可:

1
2
3
4
5
jQuery('a').queue(function(<wbr>nextItemInQueue){
    // Continue queue:
    nextItemInQueue();
});
</wbr>

当然两个方法也不完全相同,nextItemInQueue()可以在方法体内部的任何地方都可以调用,即使在一团糟的匿名函数内(典型情况是’this’对象被破坏)。当然在1.4版本前,你可以尽可能地保存一个对’this’对象的引用,但这样使用起来有点累。

要想向自定义队列中添加方法,只需将你自定义的队列名称作为第一参数,而将方法体作为第二参数传入即可:

1
2
3
4
jQuery('a').queue('customQueueName', function(){
    // Do stuff
    jQuery(this).dequeue('customQueueName');
});

需要认识的一点,为了不将该队列添加到默认的’fx’队列中,我们需要将自定义的队列名传入.dequeue()方法中,这样在队列结束后,可以保证jQuery队列可以继续执行下去。

更多的资料可以阅读‘queue’,‘dequeue’,‘jQuery.queue’

7.事件命名空间:

jQuery提供了一个命名时间名称的方法,这在编写插件或第三方组件时非常有用。当需要时,您的插件用户可以通过取消绑定这些你注册事件名称即可。

向命名空间中添加注册一个事件处理名称,只需在事件名称后添加自定义的后缀名(如:.fooPlugin):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
jQuery.fn.foo = function() {
?
    this.bind('click.fooPlugin', function() {
        // do stuff
    });
?
    this.bind('mouseover.fooPlugin', function() {
        // do stuff
    });
?
    return this;
};
?
// Use the plugin:
jQuery('a').foo();
?
// Destroy its event handlers:
jQuery('a').unbind('.fooPlugin');

取消绑定是只需调用.unbind()方法,并传入自定义事件名称即可实现。

总结:

jQuery中的隐藏功能远远不止这些,在以后的文章中会再总结一些我自己发现的功能与大家分享。

  相关解决方案