Reputation: 17415
I would add some "Li" tags in my page dynamically.
Each "Li" have some codes like this:
<li id="file-1000">
<a target="_blank" href="pack.jpg" style="display: block;" class="pirobox_gall first last">
<img alt="" src="pack_thumb.jpg" class="attached">
<i style="display: none;" class="icon-close2" id="delIcon-1000"></i>
</a>
</li>
Result:
Events:
1) I bind some events to the "a" and "i" tags like this:
$(document)
.on('mouseenter',
'#file-1000',
function () {
$('#delIcon-1000').fadeIn(200);
})
.on('mouseleave',
'#file-1000',
function () {
$('#delIcon-1000').fadeOut(200);
})
.on('click',
'#delIcon-1000',
function () {
alert('Close btn is clicked');
});
2) An other hand, the "a" tag have other assigned events on its click event (by a jQuery image slide plugin: piroBox)
So when I click on the image, I see a nice popup of my image (as a large picture) but when I click the Delete button I see the large image + "Close btn is clicked" message" together.
I want prevent "a" tag click event (parent event) when I click the Delete button (when I click it's child).
I know using stopPropagation()
is a solution but it does not work here and I don't know how can I use it in the $(document).on(....)
method.
Edit: I tried some answers but they failed and the result is like this:
Above Black Frame is >> a popup box for showing larger picture (I want prevent opening this frame)
Upvotes: 3
Views: 4562
Reputation: 421
you could try with this
$('html').on('click', '#file-1000', function(e) {
e.stopPropagation();
e.preventDefault();
alert('Close btn is clicked');
});
e.stopPropagation is ejecuted.
Great day.
Upvotes: 0
Reputation: 82297
jsFiddle Demo
It was brought to my attention that the deprecated approach first listed will in fact not work here. That is 100% correct, sorry for missing that. In fact, that scenario seems rather complex! How can you, from the outside, manage to prevent a click action which takes place prior to yours which is also attached to another element? Well, I am not sure entirely what the "best practice" is. I came up with this approach though.
Iterate from the element up the dom tree looking for click events. Collect those click events. Iterate through all of the handlers collected, and then overload them to screen for your element if the event was based on your element.
Initial Setup
$("#file-1000").click(function(e){
console.log(e);
alert("some other click");
});
$(document)
.on('mouseenter',
$('#file-1000').selector,
function () {
$('#delIcon-1000').fadeIn(200);
})
.on('mouseleave',
$('#file-1000').selector,
function () {
$('#delIcon-1000').fadeOut(200);
})
.on('click',
$('#delIcon-1000').selector,
function (e) {
alert('Close btn is clicked');
e.preventDefault();
});
Implementation of iteration as described above
function ProtectClick(element){
var handlers = [];
var elCopy = element;
do{
var handler = jQuery._data( elCopy, "events" );
if( handler != void 0 && handler.click != void 0){
handlers.push({el: elCopy, handle: handler.click});
}
elCopy = elCopy.parentNode;
}while( elCopy );
for( var h in handlers ){
(function(i){
for( var cur in handlers[i].handle ){
(function(n){
var handlerCopy = handlers[i].handle[n].handler;
var $sourced;
if( handlers[i].handle[n].selector ){
$sourced = $(handlers[i].handle[n].selector);
}else{
$sourced = $(handlers[i].el);
}
handlers[i].handle[n].handler = function(e){
if( $sourced.is(element) || element != e.target )handlerCopy(e);
};
})(cur);
}
})(h);
}
}
Call
ProtectClick($('#delIcon-1000')[0]);
I believe what you were looking for is preventDefault
$(document)
.on('mouseenter',
'#file-1000',
function () {
$('#delIcon-1000').fadeIn(200);
})
.on('mouseleave',
'#file-1000',
function () {
$('#delIcon-1000').fadeOut(200);
})
.on('click',
'#delIcon-1000',
function (e) {
alert('Close btn is clicked');
e.preventDefault();
});
Upvotes: 5