当我第一次学习jQuery时,我通常会附加这样的事件:
$('.my-widget a').click(function() {
$(this).toggleClass('active');
});
Run Code Online (Sandbox Code Playgroud)
在了解了有关选择器速度和事件委托的更多信息之后,我在几个地方读到"jQuery事件委托将使您的代码更快".所以我开始编写这样的代码:
$('.my-widget').on('click','a',function() {
$(this).toggleClass('active');
});
Run Code Online (Sandbox Code Playgroud)
这也是复制已弃用的.live()事件行为的推荐方法.这对我很重要,因为我的很多网站都在动态添加/删除小部件.上面的行为与.live()的行为完全不同,因为只有添加到现有容器".my-widget"的元素才会获得行为.如果我在代码运行后动态添加另一个html块,那么这些元素将不会获取绑定到它们的事件.像这样:
setTimeout(function() {
$('body').append('<div class="my-widget"><a>Click does nothing</a></div>');
}, 1000);
Run Code Online (Sandbox Code Playgroud)
我现在附上所有这样的事件:
$(document).on('click.my-widget-namespace', '.my-widget a', function() {
$(this).toggleClass('active');
});
Run Code Online (Sandbox Code Playgroud)
这似乎符合我的所有目标.(是的,因为某种原因它在IE中速度较慢,不知道为什么?)它很快,因为只有一个事件与单个元素相关联,而二级选择器仅在事件发生时进行评估(如果这里错误,请纠正我).命名空间非常棒,因为它可以更容易地切换事件监听器.
所以我开始认为jQuery事件应该始终绑定到$(document).
你有什么理由不想这样做吗?
这可算是最佳做法吗?如果没有,为什么?
如果您已经阅读了这一切,谢谢.我感谢任何/所有反馈/见解.
假设:
.on()//至少1.7版的jQuery读数/例子:
到目前为止,该网站上的大多数人可能都知道:
$("#someTable TD.foo").click(function(){
$(e.target).doSomething();
});
Run Code Online (Sandbox Code Playgroud)
将会比以下情况更糟糕:
$("#someTable").click(function(){
if (!$(e.target).is("TD.foo")) return;
$(e.target).doSomething();
});
Run Code Online (Sandbox Code Playgroud)
现在有多糟糕将取决于你的桌子有多少TD,但只要你有至少几个TD,这个一般原则应该适用.(注意:当然,聪明的事情是使用jQuery委托而不是上面的代码,但我只是试图用明显的区别来做一个例子).
无论如何,我向同事解释了这个原则,他们的回答是"嗯,对于站点范围的组件(例如,日期选择INPUT),为什么停在那里?为什么不将每种类型的组件的一个处理程序绑定到身体本身?" 我没有一个好的答案.
显然使用委托策略意味着重新思考如何阻止事件,这是一个缺点.此外,假设你有一个页面,你有一个"TD.foo",不应该有一个事件连接到它.但是,如果您理解并愿意解决事件冒泡变化,并且如果您执行"如果您将.foo放在TD上,它始终会将事件连接起来"的策略,那么这些似乎都不是很重要.
我觉得我必须遗漏一些东西,所以我的问题是:将所有站点范围的组件的所有事件委托给BODY还有其他任何缺点(而不是直接将它们绑定到所涉及的HTML元素,或委托它们)到非BODY父元素)?