JQuery事件处理程序 - 什么是“最佳”方法

时间:2012-03-16 00:38:09

标签: 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";
    });
})();

我发现了一些似乎有效的情况,而另一种则没有。例如,处理程序2 下面的处理程序2 处理程序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>

2 个答案:

答案 0 :(得分:19)

我的猜测是你看到了行为上的差异,因为页面中的某些对象是动态添加/删除的,你需要委托事件处理才能自动为新添加的对象提供事件。

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

行为#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>

如果你有大量的对象(即使它们是静态的),那么委托事件处理将更有效地安装,因为它为所有对象安装了一个事件处理程序,而不是为每个单独的对象安装了数千个。

如果您有中等或少量的静态对象,则将事件处理程序直接绑定到它们是最有效的。最初将事件处理程序绑定到每个对象需要花费更多的时间,但在事件发生时效率最高。

答案 1 :(得分:-1)

如果你想要最好我可以推荐使用.on(),因为你可以创建某种通用方法,通过传递参数(即事件名称)也可以重用于其他事件。我通常使用.on()< / p>