jQuery事件处理程序-什么是“最佳"事件处理程序?方法 [英] JQuery Event Handlers - What's the "Best" method

查看:66
本文介绍了jQuery事件处理程序-什么是“最佳"事件处理程序?方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下在JQuery中附加事件处理程序的方式之间有什么区别?

(function () {

    var $body = $("body");

    $('button').click(function () {
        console.log(this) + " - 1";
    });

    $('button').on('click', function () {
        console.log(this) + " - 2";
    });

    $(document).on('click', 'button', function () {
        console.log(this) + " - 3";
    });

    $body.on('click', 'button', function () {
        console.log(this) + " - 4";
    });

    $body.find('button').on('click', function () {
        console.log(this) + " - 5";
    });
})();

我发现某些情况下,其中一种似乎可行,而另一种则无效.例如,下面的 Handler 2 不能工作,而 Handler 1 可以工作.为了完成这项工作,我必须实现效率明显较低的 Handler 3 .

$retrieveCust = $("#bxRetrieveCustomer");

// Handler 1
$retrieveCust.find(".icoX").on("click", function () {
    // DO SOMETHING
});

// Handler 2
$retrieveCust.find(".tag-open").on("click", function () {
    // DO SOMETHING
});

// Handler 3
$(document).on("click", ".tag-open", function (event) {
    // DO SOMETHING
}); 

这是HTML

<div class="box" id="bxRetrieveCustomer">
<h1>RETREIVE CUSTOMER</h1>
<div class="icoX">X</div>
<div class="box-liner10">
    <table>
        <tr>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Date of Birth</th>
            <th>Email</th>
            <th>password</th>
            <th></th>
        </tr>
        <!-- ko foreach: Customers -->
        <tr>
            <td data-bind="text: FirstName"></td>
            <td data-bind="text: LastName"></td>
            <td data-bind="text: DateOfBirth"></td>
            <td data-bind="text: Email"></td>
            <td data-bind="text: Pwd"></td>
            <td><a class="tag-open"></a></td>
        </tr>
        <!-- /ko -->
    </table>
</div>
</div>

解决方案

我的猜测是,您看到的是行为上的差异,因为页面中的某些对象正在动态添加/删除,并且您需要委派事件处理才能自动具有新添加对象的事件.

在您的各种示例中,这里有两种基本的行为类型:

行为1:静态事件绑定

$('button').click(function () {
    console.log(this) + " - 1";
});

$('button').on('click', function () {
    console.log(this) + " - 2";
});

$body.find('button').on('click', function () {
    console.log(this) + " - 5";
});

以上三个都将单击处理程序直接附加到第一次运行代码时页面中存在的每个按钮对象.这些基本上是相同的. .click()语法只是一个快捷方式. $body.find('button')在功能上等同于$('button'),因为它们都选择了主体中的所有按钮.

注意:这些事件处理程序将仅附加到首次运行此代码时存在的按钮对象.随后添加到文档中的任何按钮对象都不会附加事件处理程序.

行为2:动态或委派的事件绑定

$(document).on('click', 'button', function () {
    console.log(this) + " - 3";
});

$(document.body).on('click', 'button', function () {
    console.log(this) + " - 4";
});

这两个使用委托事件处理来监视单击,这些单击会冒泡到文档或主体对象.这些同样相似.这些将处理源自按钮标签的任何单击事件.由于事件处理程序没有直接附加到按钮对象,因此按钮可以在页面中来回移动,并且随时存在的所有按钮对象都将获得此处理程序的行为.

通常不建议绑定绑定到documentbody对象的委托方法.实际上,这就是为什么不推荐使用.live()的原因,因为这就是这样做的原因,并且可能导致性能问题.问题是,如果您有很多委派的事件都绑定到同一对象,那么每次事件发生并冒泡到该对象时,jQuery都必须将原始选择器与许多不同的选择器进行比较,以了解要使用哪个处理程序打电话.

将委托事件绑定到尽可能接近实际目标对象的父对象要好得多,但是显然您必须选择一个不会添加/删除的父对象(您需要一个不断添加的父对象)在页面中.)

在更具体的代码示例中,假设bxRetrieveCustomer div不是动态创建的,则应更改此内容:

$(document).on("click", ".tag-open", function (event) {
    // DO SOMETHING
}); 

对此:

$("#bxRetrieveCustomer").on("click", ".tag-open", function (event) {
    // DO SOMETHING
}); 

仍将委派事件处理程序,但将事件处理程序绑定到与实际对象更近的位置,因此它将更有效地工作.

效率

至于哪一个最好,取决于:

如果您具有在运行要绑定事件的事件绑定代码之后创建的对象,那么您将希望对事后未动态创建的最接近的祖先对象使用委托事件处理. /p>

如果您有大量对象(即使它们是静态的),则委托事件处理将更加有效地安装,因为它将为所有对象安装一个事件处理程序,而不是为每个对象安装数千个事件处理程序.

如果静态对象的数量较少,那么将事件处理程序直接绑定到它们是最有效的.最初将事件处理程序绑定到每个对象将花费一点时间,但是在事件发生时效率最高.

What's the difference between the following ways of attaching an event handler in JQuery?

(function () {

    var $body = $("body");

    $('button').click(function () {
        console.log(this) + " - 1";
    });

    $('button').on('click', function () {
        console.log(this) + " - 2";
    });

    $(document).on('click', 'button', function () {
        console.log(this) + " - 3";
    });

    $body.on('click', 'button', function () {
        console.log(this) + " - 4";
    });

    $body.find('button').on('click', function () {
        console.log(this) + " - 5";
    });
})();

I have found some cases where one seems to work and the other does not. For example Handler 2 below, does not work while Handler 1 does. In order to make this work I had to implement Handler 3 which is obviously less efficient.

$retrieveCust = $("#bxRetrieveCustomer");

// Handler 1
$retrieveCust.find(".icoX").on("click", function () {
    // DO SOMETHING
});

// Handler 2
$retrieveCust.find(".tag-open").on("click", function () {
    // DO SOMETHING
});

// Handler 3
$(document).on("click", ".tag-open", function (event) {
    // DO SOMETHING
}); 

Here's the HTML

<div class="box" id="bxRetrieveCustomer">
<h1>RETREIVE CUSTOMER</h1>
<div class="icoX">X</div>
<div class="box-liner10">
    <table>
        <tr>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Date of Birth</th>
            <th>Email</th>
            <th>password</th>
            <th></th>
        </tr>
        <!-- ko foreach: Customers -->
        <tr>
            <td data-bind="text: FirstName"></td>
            <td data-bind="text: LastName"></td>
            <td data-bind="text: DateOfBirth"></td>
            <td data-bind="text: Email"></td>
            <td data-bind="text: Pwd"></td>
            <td><a class="tag-open"></a></td>
        </tr>
        <!-- /ko -->
    </table>
</div>
</div>

解决方案

My guess is that you're seeing a difference in behavior because some objects in your page are being dynamically added/removed and you need delegated event handling in order to automatically have events for newly added objects.

Among your various examples, there are two basic types of behaviors here:

Behavior #1: Static Event Binding

$('button').click(function () {
    console.log(this) + " - 1";
});

$('button').on('click', function () {
    console.log(this) + " - 2";
});

$body.find('button').on('click', function () {
    console.log(this) + " - 5";
});

The above three all attach a click handler directly to each button object that exists in the page at the time the code is first run. These are basically identical. The .click() syntax is just a shortcut. The $body.find('button') is functionally equivalent to $('button') since both select all buttons in the body.

Note: these event handlers will only be attached to the button objects that exist when this code is first run. Any button objects that are subsequently added to the document will not have an event handler attached to them.

Behavior #2: Dynamic or Delegated Event Binding

$(document).on('click', 'button', function () {
    console.log(this) + " - 3";
});

$(document.body).on('click', 'button', function () {
    console.log(this) + " - 4";
});

These two use delegated event handling to watch for clicks that bubble up to the document or body objects. These are likewise similar. These will handle any click event that originated on a button tag. Since the event handler is not attached directly to the button object, buttons can come and go in the page and all button objects that exist at any time will get this handler behavior.

It is generally NOT recommended to bind delegated methods bound to the document or body objects. In fact, this is why .live() has been deprecated because that's what it did and it can cause performance issues. The issue is that if you get lots of delegated events all bound to the same object, then every time an event occurs and it bubbles up to this object, jQuery has to compare the originating selector to a lot of different selectors to see which handler to call.

It is much better to bind delegated events to a parent object that is as close to the actual target objects as possible, but obviously you must pick a parent object that won't be added/removed (you need one that is constantly in the page).

In your more specific code example, assuming the bxRetrieveCustomer div is not created dynamically, you should change this:

$(document).on("click", ".tag-open", function (event) {
    // DO SOMETHING
}); 

to this:

$("#bxRetrieveCustomer").on("click", ".tag-open", function (event) {
    // DO SOMETHING
}); 

Which will still be delegated event handling, but will bind the event handler much closer to the actual object so it will work more efficiently.

Efficiency

As for which is best, it depends:

If you have objects that are created after you run the event binding code that you want events bound to, then you will want to use delegated event handling on the closest ancestor object that is not dynamically created after-the-fact.

If you have a very large number of objects (even if they are static), then delegated event handling will install much more efficiently because it installs one event handler for all of them rather than thousands for each individual object.

If you have a medium or small number of static objects, then binding event handlers directly to them is the most efficient. It will take a tiny bit more time to initially bind an event handler to each object, but then be the most efficient at the time of the event.

这篇关于jQuery事件处理程序-什么是“最佳"事件处理程序?方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆