We attach our event handlers using jQuery for DOM elements either

1)directly —

    $(#elemId).bind("click",function(){ …//event handler code}); OR

2) by delegation. —

         $(document).delegate("#elemId","click",function(){ …//event handler code});

We also come accross a situtation whereby we need to execute these attached event handlers manually from our code. To do this we can use either .trigger() API in jQuery on the element.

       $(#elemId).trigger("click") 

In some scenarios we only want to execute the event handlers we attached but we do not want to execute the default action that is associated with that event. We can acheive this by using .triggerHandler() API in jQuery on element

$(#elemId).triggerHandler("click");

e.g. we can attach "click" event on a list of "checkboxes" and we can execute an event handler when any of the checkboxes are checked/unchecked. Here the default action of click event for a checkbox is that either that checkbox gets checked /uncehcked(i.e. that status of the checkbox changes.) So. in some scenarios we might not want to change the status of the checkbox when it is clicked but we would like to execute the code in our event handler.As explained aboce this can be achieved in jQuery by calling .triggerHandler() instead of .trigger() to fire the event.

However this does not work when we attach event to a DOM element by delegation. What is the other way to execute event handlers without executing default action in case of event delegation?

Please check the difference in following JSfiddles: for direct event handling :

       http://jsfiddle.net/g2TWh/7/

for delegated event handling :

        http://jsfiddle.net/g2TWh/8/ 

(Note that alert in event handler function does not appear when you click "Run")

有帮助吗?

解决方案

One solution I found to this when I came across the same scenario was to check if the event was triggered, and if so, prevent the default action. This way rather than triggering the handler (which isn't possible with delegation as mentioned above), you can trigger the full event and just condition the action based on the event properties. Take this for example:

//attach an event "click" by delegation
$(document).delegate("#childinput1", "click.test", function (e) {
    // prevent default if this event was triggered
    if (!!e.isTrigger) {
     e.preventDefault();   
    }
    alert('in delegated  "click" event handler');
});
testTrigger();

function testTrigger() {
    $("#childinput1").trigger("click.test");
}

Here's the modified JSFiddle: http://jsfiddle.net/x9d9yjtv/

其他提示

According to JQuery API:

Events created with .triggerHandler() do not bubble up the DOM hierarchy; if they are not handled by the target element directly, they do nothing.

Because you use event delegation, the event can not bubble to document that suppose to handle the event

The other way would be adding custom event and using event.preventDefault() in its handler:

    //attach an event "click" by delegation
$(document).on("customevent", "#childinput1", function (e) {
    e.preventDefault();
    alert('in delegated  "custom" event handler');
});
$(document).on("click", "#childinput1", function (e) {
    alert('in delegated  "click" event handler');
});
testTrigger();

function testTrigger() {
    $("#childinput1").trigger("customevent");
}

Fiddle

By the way you if you use jquery 1.7+ you should could use "$.on" instead of "$.delegate":

As of jQuery 1.7, .delegate() has been superseded by the .on() method. For earlier versions, however, it remains the most effective means to use event delegation.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top