简体   繁体   中英

JQuery click function not working on button within parent element which has it's own click function

I have a button which needs to run a javascript function when clicked.

The problem is that this button lives within another element which has it's own click function which seems to be preventing that of the button from running.

Here's the code:

         <a id="login">Login
            <span>
                <span style="display:block; padding:0 0 5px 0;">
                    content here...
                </span>
                <input type="button" id="forgotten" value="test" />
            </span>
         </a>

And here's the javascript:

$("#login").click( function() {
    $("#login > span").slideDown();
});
$('body').click( function() {
    if ($("#login > span:visible")) {
        $("#login > span").slideUp();
    }
});
$('#login, #login > span').click( function(event){
    event.stopPropagation();
});

$("#forgotten").live("click", function() {
    // ... Run function here...
});

I have a feeling it might be because of the stopPropagation part of the code.

Any ideas?

I have a feeling it might be because of the stopPropagation part of the code.

Correct, combined with the fact you're using live to hook the click of the button. If you hooked it up directly, the button would get the event first. But because you've used live , the button click event doesn't get fired until/unless the click reaches all the way up to the document , because that's how live works: It hooks the event at the document level and then, when the event reaches it, it looks to see if the selector you've used matches the element that was actually clicked or any of its ancestors. In your case, it never actually gets there, because along the way it travels through the #login element, which stops the event bubbling any further with stopPropagation .

So to make this work, you'll need to hook the button it up normally instead of using live . From your structure, there doesn't immediately seem to be any reason for using live anyway (though of course it's always possible there's something you haven't shown us). If you're adding the button dynamically after all of the #login click handlers are attached, you'll have to hook it when you add it.

The live function attaches the handler to the document element and waits for the event to propagate. You are correct in thinking that preventing the event from propagating is preventing the handler being called. You can work around this using the delegate method (similar to live, but with specified parent elements rather than document ):

$('#login, #login > span').delegate("#forgotten", "click", function() {
  // ... Run function here...
});

Or in jQuery 1.7+ the on method can be used:

$('#login, #login > span').on("click", "#forgotten", function() {
  // ... Run function here...
});

Use delegate() ( http://api.jquery.com/delegate/ ) or on() (only with jQuery > 1.7) ( http://api.jquery.com/on/ ) to attach the hook to the child you want. Delegate / On do not bubble / propagate.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM