Reputation: 12988
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?
Upvotes: 3
Views: 430
Reputation: 41757
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...
});
Upvotes: 1
Reputation: 474
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.
Upvotes: 0
Reputation: 1074038
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.
Upvotes: 1