7. event:统一事件模型
“事件沿着对象树传播”这一图景是面向对象界面编程模型的精髓所在。对象的复合构成对界面结构的一个稳定的描述,事件不断在对象树的某个节点发生,并通过冒泡机制向上传播。对象树很自然的成为一个控制结构,我们可以在父节点上监听所有子节点上的事件,而不用明确与每一个子节点建立关联。
jQuery除了为不同浏览器的事件模型建立了统一抽象之外,主要做了如下增强:
A. 增加了自定制事件(custom)机制. 事件的传播机制与事件内容本身原则上是无关的, 因此自定制事件完全可以和浏览器内置事件通过同一条处理路径, 采用同样的监听方式. 使用自定制事件可以增强代码的内聚性, 减少代码耦合. 例如如果没有自定制事件, 关联代码往往需要直接操作相关的对象
$(‘.switch, .clapper’).click(function() {
var $light = $(this).parent().find(‘.lightbulb’);
if ($light.hasClass(‘on’)) {
$light.removeClass(‘on’).addClass(‘off’);
} else {
$light.removeClass(‘off’).addClass(‘on’);
}
});
而如果使用自定制事件,则表达的语义更加内敛明确,
$(‘.switch, .clapper’).click(function() {
$(this).parent().find(‘.lightbulb’).trigger(‘changeState’);
});
B. 增加了对动态创建节点的事件监听. bind函数只能将监听函数注册到已经存在的DOM节点上. 例如
$(‘li.trigger’).bind(‘click’,function(){}}
如果调用bind之后,新建了另一个li节点,则该节点的click事件不会被监听.
jQuery的delegate机制可以将监听函数注册到父节点上, 子节点上触发的事件会根据selector被自动派发到相应的handlerFn上. 这样一来现在注册就可以监听未来创建的节点.
$(‘#myList’).delegate(‘li.trigger’, ‘click’, handlerFn);
最近jQuery1.7中统一了bind, live和delegate机制, 天下一统, 只有on/off.
$(‘li.trigger’).on(‘click’, handlerFn); // 相当于bind
$(‘#myList’).on(‘click’, ‘li.trigger’, handlerFn); // 相当于delegate
8. 动画队列:全局时钟协调
抛开jQuery的实现不谈, 先考虑一下如果我们要实现界面上的动画效果, 到底需要做些什么? 比如我们希望将一个div的宽度在1秒钟之内从100px增加到200px. 很容易想见, 在一段时间内我们需要不时的去调整一下div的宽度, [同时]我们还需要执行其他代码. 与一般的函数调用不同的是, 发出动画指令之后, 我们不能期待立刻得到想要的结果, 而且我们不能原地等待结果的到来. 动画的复杂性就在于:一次性表达之后要在一段时间内执行,而且有多条逻辑上的执行路径要同时展开, 如何协调?










