jQuery事件绑定和处理

jQuery event binding and handling

本文关键字:处理 绑定 事件 jQuery      更新时间:2023-09-26

我见过很多这样的jQuery代码,不用说我不喜欢它:

<div id="myDiv">
    <a class="clickable" href="#">Click Me</a>
    <a class="clickable" href="#">Click Me</a>
    <a class="clickable" href="#">Click Me</a>
    <a class="clickable" href="#">Click Me</a>
</div>
<script>
    $(document).ready(function(){
        $('clickable').click(function(){
            // Do some stuff...
        });
    });
</script>

我意识到人们这样做是因为上面的事件绑定和处理需要在页面上可用的html结构,但这会导致在网站的所有视图中混合表示、逻辑和配置。而且,这使得用任何调试器来调试逻辑都非常困难。

所以,我开始这样编码,在一个单独的。js文件(这里):

// BEGIN: Event Handlers
    var onLoad = function(){
        $('.clickable').data('clicked', false);
    };
    var onMyDivClick = function(){
        var clicked = $(this).data('clicked');
        if (clicked) {
            $(this).trigger('myCustomEvent');
        } else {
            alert('you clicked me');
            $(this).data('clicked', true);
        }
    };
    var onMyCustomEvent = function(){
        $(this).css('color', 'dimGray');
        alert('please don''t click me again');
    };
// END: Event Handlers
// BEGIN: Event Binding
    $(window).on('load', onLoad);
    $(document).on('click', '.clickable', onMyDivClick);
    $(document).on('myCustomEvent', '.clickable', onMyCustomEvent);
// END: Event Binding

现在,我不需要关心页面上的结构。我不需要在$(document).ready(function(){});中包装所有内容,也不需要关心结构是否会被ajax加载。

问题1
这种方法有什么缺点吗?到目前为止,我还没有找到。但是在重构我们网站上的大部分代码之前,我想听听可能的注意事项。

问题2
如何使用最新的jQuery特性进一步扩展这种方法呢?

我知道这种方法有一个缺点。它写在.on()Event performance一节中。

在文档树的顶部附近附加许多委托事件处理程序会降低性能。每次事件发生时,jQuery必须将该类型的所有附加事件的所有选择器与从事件目标到文档顶部的路径中的每个元素进行比较。为了获得最佳性能,请在尽可能靠近目标元素的文档位置附加委托事件。避免过度使用documentdocument。body用于大型文档的委托事件。

所以当你将所有事件绑定到document后,它的性能会变差。

附加注释中,有一些东西不能用这种方法工作,例如load, scrollerror

查看框架,它们已经为您完成了样板工作。到目前为止,我只使用了knockout,但我会链接到其他一些。

  • knockout对于数据/事件绑定非常有效- http://knockoutjs.com/
  • 主干- http://backbonejs.org/
  • ember js - http://emberjs.com/
  • angularjs - http://angularjs.org/

"Hello World" in knockout:

http://knockoutjs.com/examples/helloWorld.html

<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>
<h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
// Here's my data model
var ViewModel = function(first, last) {
    this.firstName = ko.observable(first);
    this.lastName = ko.observable(last);
    this.fullName = ko.computed(function() {
        // Knockout tracks dependencies automatically. It knows that fullName depends on firstName and lastName, because these get called when evaluating fullName.
        return this.firstName() + " " + this.lastName();
    }, this);
};
ko.applyBindings(new ViewModel("Planet", "Earth")); // This makes Knockout get to work

这对我来说是对工程的尖叫。为了避免在文档中出现代码。准备好了,在视图中避免视图逻辑,你会引入更多的复杂性。

您的方法直接绑定到document,然后检查dom中单击的内容。然后,为点击的内容触发第二个事件,这是您的逻辑所在。

对于一个或两个元素来说是可以的。这并不是典型的应用。当你有5个元素都需要做一些不同的事情时,会发生什么?10点怎么样?也许15 ?

你的"简单"事件处理程序将成为一个漂亮的大开关(或者更糟的是,if和嵌套if)。突然间,添加一个新的处理程序变得不那么容易了。改变一个已经存在的事件也不是。

你最好找一个能提供你想要的分离的框架。试图硬塞进这样的东西来"帮助"组织代码,最终会让你吃亏。代码中的大多数复杂性都源于工程师使其"简单"、"更好"answers"面向未来"。

这不是要打击你或你的思想。你的想法是对的:责任分离是件好事。我只是觉得你的方法不是最好的。

正如另一个帖子回答的那样,angular、backbone和ember(以及更多)提供了完成你想要的东西的手段。另外,您不必维护您选择的库:)