一个专注于技术的IT男
Working with Events, part 1
原文地址:http://www.learningjquery.com/2008/03/working-with-events-part-1
原文作者: Karl Swedberg
CSS和JavaScript有很多的不同,其中大多数区别都很明显不用说出来。然而,他俩的一处区别值得一 提,因为这个区别常常引起困惑和吃惊,尤其是对那些从CSS专家转职为jQuery新手的人。事实上,这是早在2006年我向jQuery邮件列表提出的 第一个问题。从那之后,我至少每周能看到类似的问题,有时候甚至每天都有,尽管jQuery已经提供了FAQ page and 这 三个 插件在解决这个问题。
CSS和JavaScript如何不同?
举个例子,假如我们html文档中有”<button>Alert!</button>“,我们想要为它加上点击事件处理,让它在被点击的时候产生一个alert消息。在jQuery中用如下的代码实现:
$(document).ready(function() {
$('button.alert').click(function() {
alert('this is an alert message');
});
});
这里我们在页面加载完成之后为定义了class等于”alert”的button注册一个点击事件。按钮已经在这了,我们为其绑定了一个点击事件。如果我们之后再动态插入第二个按钮<button>,然而这个时候第二个按钮是完全不知道点击事件处理器的。点击事件在第二个按钮存在之前已经处理完了。因此第二个按钮不会产生alert消息。
对新加的Elements事件处理器不起作用
$('#create-button').click(function() {
if ( $('button.alert').length <2) {
$('<button class="alert">Not another alert').insertAfter(this);
}
return false;
});
对新加的Element CSS依然是工作的
<ul id="list1" class="eventlist"> <li>plain</li> <li class="special">special <button>I am special</button></li> <li>plain</li> </ul>
- plain
- special
- plain
$(document).ready(function() {
$('#list1 li.special button').click(function() {
var $newLi = $('<li class="special">special and new <button>I am new</button></li>');
$(this).parent().after($newLi);
});
});
事件委派: 让事件拥抱新的Elements
$(document).ready(function() {
$('#list2').click(function(event) {
var $newLi = $('<li class="special">special and new <button>I am new</button></li>');
});
$(document).ready(function() {
$('#list2').click(function(event) {
var $newLi = $('<li class="special">special and new <button>I am new</button></li>');
var $tgt = $(event.target);
if ($tgt.is('button')) {
$tgt.parent().after($newLi);
}
// next 2 lines show that you've clicked on the ul
var bgc = $(this).css('backgroundColor');
$(this).css({backgroundColor: bgc == '#ffcccc' || bgc == 'rgb(255, 204, 204)' ? '#ccccff' : '#ffcccc'});
});
});
- plain
- special
- plain
var list2 = document.getElementById('list2');
list2.onclick = function(e) {
var e = e || window.event;
var tgt = e.target || e.srcElement;
if (tgt.nodeName.toLowerCase() == 'button') {
// do something
}
};
正如你看到的,代码有点纠缠。
使用事件代理的另一个巨大的好处
$(document).ready(function() {
$('table').click(function(event) {
var $thisCell, $tgt = $(event.target);
if ($tgt.is('td')) {
$thisCell = $tgt;
} else if ($tgt.parents('td').length) {
$thisCell = $tgt.parents('td:first');
}
// now do something with $thisCell
});
});
注意上面的代码的else块中我考虑了点击单元格内子元素的情况,但这只是事件代理带来巨大性能提升的同时伴随的一个小小的不方便。
下期带来
在本教程的第二部分的,我们将会通过小心放置函数调用位置的方法来将事件传递到新创建的元素上。当然也会检查非绑定的事件和使用命名空间的事件。同时,我希望大家觉得这一部分的教程是有用的。如果我在文章中有任何错误,特别是用辞方面的,请不要迟疑马上指出来。
本文包含的脚本文件:
| 打印文章 | 这篇文章由Jacky于2010/01/07 17:18发表在JavaScript。你可以订阅RSS 2.0 也可以发表评论或引用到你的网站。 |


