Вопрос

According to jQuery's API site, the on() event, when attached on a DOM node, supports delegation. As far as I can tell, this means you can have 2 DOM nodes, with the event starting at the inside node or somewhere inside it, then bubbling up to the outside node. Before this, and when you specify only one node to on(), the event bubbles up to the absolute outside node of the document, which is called document (and I believe the exact same thing happens if you have document as your "outside" DOM node). The "shortcut" events for on(), such as click() and change(), seem not to implement delegation, meaning the event has to bubble all the way up to the top of the document. If I've butchered this explanation, which I'm sure I have, please correct me. Why is this?

For example, I can have

$("form").on("click", "button", function() {
    window.location.href = "submit-page.php";
});

which is delegation, or

$("button").on("click", function() {
    window.location.href = "submit-page.php";
});

where the event would bubble out of the document. However, click(), for example, seems only able to have the 2nd form,

$("button").click(function() {
    window.location.href = "submit-page.php";
});
Это было полезно?

Решение

.on() ONLY supports delegation when used with two selectors as in:

$("#parent").on("click", "#child", fn);

The shortcuts like .click() don't support the two selector syntax and thus don't support delegation in the same way.


In your code examples, these two blocks of code do not have identical behavior:

$("form").on("click", "button", function() {
    window.location.href = "submit-page.php";
});

$("button").on("click", function() {
    window.location.href = "submit-page.php";
});

The first one uses event delegation and will respond to a propagated event that originated on a "button" object even if that button was added long after the event handler was added. The second is direct event handling only and will only attach event handlers to objects that exist at the time the event handling code is initially run. That's the difference between direct event handling and delegated event handling.

Another subtle difference is that the first one only responds to button events that are contained within a form (events propagate up through a form object) whereas the second one respond to events from any button in the page that existed at the time the event handler was installed even ones not in a form.


In your code examples, these two do have the same behavior (both are direct event handlers and will only work on objects that exist at the time the event handler is installed):

$("button").on("click", function() {
    window.location.href = "submit-page.php";
});

$("button").click(function() {
    window.location.href = "submit-page.php";
});

Другие советы

The click function used to be an alias for bind, before on existed. bind would attach an event directly to the specified element.

More info on bind here: http://api.jquery.com/bind/

It looks like they never felt the need to extend the functionality beyond what was already there after on was added, and simply ported the internal code to use on instead of bind.

In either case, I generally just use on and skip the shortcut methods like click.

There's no bubbling with the non-delegated methods. They just attach the handler to the specific element(s) that you bind them to. Bubbling is used by the delegation form of on: When you click on the button, the event bubbles up to the form. The generic handler that's attached there then checks whether the target of the event matches the selector argument, and in that case it runs the handler you supplied.

Delegation has more runtime overhead than normal binding, because the internal jQuery handler has to run whenever there's a click anywhere in the containing element -- it can't attach the handler to the more specific elements because they may not exist at the time you establish the binding. Since this is only needed in special circumstances, the shortcut syntax doesn't provide a way to do this.

You might want to submit a suggestion to the jQuery Forum. It probably wouldn't be too difficult to enhance the shortcut methods to allow syntax like:

$("form").click("button", function() { ... });

which would be short for:

$("form").on("click", "button", function() { ... });

As far as I can tell, this doesn't conflict with any existing syntax.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top