How to use event.stopPropagation() in delegate() - javascript

My Code is like following in html:
<li class="arrow">
<div>
remove
</div>
</li>
And I bind my elements using deligate() jquery method (because elements appear dynamically)
$obj.delegate(".arrow", "click", function() {
alert("clicked on arrow");
});
$obj.delegate(".anchor", "click", function(event) {
event.stopPropagation();
alert("anchor clicked");
});
My Problem is, when I click on ".anchor" then both events occurs. can anyone tell me how to use event.stopPropagation() in this context? I tried like the above but not working. Is there any other way to do this?
EDIT: I tried with calling event.isPropagationStopped(), and it returns true. but still both events called.

There is limitations when delegate or live is used and stopPropagation.
You return false in you handler to prevent both eventPropagation and default
Try
$obj.delegate(".anchor", "click", function(event) {
alert("anchor clicked");
return false;
});

My understanding is that with .delegate and .live you need to return false. I believe this is because of how the event is attached - not to the element but to it's ancestor.
Here is an example:
http://jsfiddle.net/G3k8Z/

Related

prevent click event from element but not from <a> children

my code looks like this:
<div class="disabledClickevent">
<ul>
<li><a>link1</a></li>
<li><a>link2</a></li>
</ul>
</div>
the div has a click event that gets disabled with return false;
my problem is that this also disables the <a> links
$(document).on('click','.disabledClickevent' function(e) {
if( e.target !== this )
//clicked out side
return;
//clicked inside
});
I would do this:
$(".disabledClickevent").on("click", ":not(a)", function(e) {
//do stuff with your div
});
This excludes a from the click event.
Could be a solution:
$('.disabledClickevent').on('click',function(e){
if($(e.target).is(':not(a)'))
return false;
});
Or set click handler to links:
$('.disabledClickevent a').click(function(e){
e.stopPropagation();
});
you can use the :not() selector in jQuery
check this link out http://api.jquery.com/not-selector/
hope this helps.
If you don't plan to add new "disabledClickevent" divs to the page via Javascript, you could just do this:
$('.disabledClickevent').click(function() {...});
or
$('.disabledClickevent').bind('click', function() {...});
That attaches the event only to the already-existing div, without doing any sort of delegation, so the links will just work normally as you want them to.
To be clear, this is only a viable solution if all of the "disabledClickevent" divs that you plan to have already exist on the page at the time that you bind the event.

jQuery on(click) doesn't work but on(hover) does

After initialize js I create new <div> element with close class and on("click") function doesn't work.
$(document).on('click', '.post-close', function () {
alert("hello");
});
but on('hover') work perfectly.
$(document).on('hover', '.post-close', function () {
alert("hello");
});
but I need to make it work on click.
It's because you're not preventing the default behaviour of the browser. Pass e into your handler and then use e.preventDefault()
$(document).on('click', '.post-close', function (e) {
e.preventDefault();
alert("hello");
});
Edit
Also, bind the handler before creating the new <div>
why not use something like
$('.post-close').click(function(){
//do something
});
If the element was added dynamically use:
$(document).on('click', '.post-close', function(){
//do something
});
edit:
like danWellman said, you can add the preventDefault IF you want to make sure no other code is executed. otherwise use the code above.
edit2:
changed the .live to .on
It's an old post but I've had a exactly same problem (element created dynamically, hover works, but click doesn't) and found solution.
I hope this post helps someone.
In my case, I found ui-selectable is used for parent element and that was preventing from click event propagate to the document.
So I added a selector of the button element to ui-selectable's 'cancel' option and problem solved.
If you have a similar probrem, check this
Try turn of libraries for parent element
You're not using stopPropagation() in parent element ?

The "not:()" selector isn't working with ".live()" when event binding

When I added live() to some mousedowns, my not: conditional stopped working.
$("body :not(" + _self.somevar + ")").live('mousedown',
function(event){
event.stopPropagation();
// some more code
}
When it wasn't live() it worked. Now that I use live(), when I mousedown on that item, it fires when it shouldn't.
Anyone know why not: is no longer adhered to?
You can update your .live() method to .on() (to work with new versions of jQuery). So you need apply on the document an event of mousedown selecting the body :not(#notAcceptedElement). Example:
HTML:
<div id="notAccept">Not Accept Mousedown</div>
<div id="accept">Accept Mousedown</div>
JS (jQuery 1.6):
$('body :not(#notAccept)').live('mousedown', function(ev) {
console.log(ev.target);
$('#accept').clone().appendTo(document.body);
});
JS (jQuery edge/1.8):
$(document).on('mousedown', 'body :not(#notAccept)', function(ev) {
console.log(ev.target);
$('#accept').clone().appendTo(document.body);
});
​
Live example: jsFiddle jQuery-1.6, jsFiddle jQuery-edge.
I hope you know only one body tag you can use in a HTML page. In your case its better if you try to attach event for id/class. and syntax will be something like this,
For id of element
$("#not:'+ _self.somevar'+").live('mousedown',
function(event){
event.stopPropagation();
// some more code
}
For class of element
$(".not:'+ _self.somevar'+").live('mousedown',
function(event){
event.stopPropagation();
// some more code
}

jQuery click function acting strange when adding/removing classes

I have two list items that, when clicked, should change classes from '.off' to '.on'. Only one element should be '.on' at a time so when one is already turned on and the other is clicked both elements should change classes from '.off' to '.on' and vice versa. If a list item with a class of '.on' is clicked it should change classes to '.off'
The problem I am having is when a list item with class '.on' is clicked it still runs the click function as if it had a class of '.off'
My html:
<ul>
<li>ABOUT</li>
<li>SUBMIT</li>
</ul>
My javascript (running on jQuery 1.7.1)
$('.off').click(function(event) {
event.preventDefault();
$(".on").addClass("off").removeClass("on");
$(this).addClass("on").removeClass("off");
});
$('.on').click(function(event) {
event.preventDefault();
$(this).addClass("off").removeClass("on");
});
Does anyone know what is going on here? Is there something wrong in my code or have I encountered some sort of bug here?
http://jsfiddle.net/ZC3CW/6/
The selectors you're using to bind the event using click() are used to select the elements to add the event handler to. The selector is not considered when the handler is run.
You should be looking for something more like this:
$('li').click(function(event) {
event.preventDefault();
if ($(this).hasClass('off')) {
$(".on").addClass("off").removeClass("on");
$(this).addClass("on").removeClass("off");
} else { // $(this).hasClass('on');
$(this).addClass("off").removeClass("on");
}
});
You might want to make the li selector more explicit by adding a class/id to the ul or li's.
To confuse things further, you could also do this (if you're using jQuery > 1.7);
$(document).on('click', '.off', function(event) {
event.preventDefault();
$(".on").addClass("off").removeClass("on");
$(this).addClass("on").removeClass("off");
});
$(document).on('click', '.on', function(event) {
event.preventDefault();
$(this).addClass("off").removeClass("on");
});
This is because the .on() function works by attaching the event handler to the selected elements (document), and will only execute the handler (the function) on the event specified (click) if the element that the event originated from matches the selector .off at the time the event fired, not at binding time.
I would suggest adding a click handle to a different selector, this should work for you...
$("ul li a").click(function(e){
e.preventDefault();
if($(this).hasClass("off")){
$("ul li a").addClass("off").removeClass("on");
$(this).addClass("on").removeClass("off");
}
else{
$(this).addClass("off").removeClass("on");
}
});
The problem is that jQuery handlers get attached at page load and remain the same regardless of changing their classes. Use live('click', handler) on('click', handler) instead of click().
Edit: just noticed that .live() is deprecated in jQuery 1.7.
The problem as I see it is that your "on" class is not in play at the time of the click event, so your $('.on').click method is never being called.
Try re-assigning your events after changing classes (example follows) :
var assignClicks = function () {
$('.off').click(function(event) {
event.preventDefault();
$(".on").addClass("off").removeClass("on");
$(this).addClass("on").removeClass("off");
assignClicks();
});
$('.on').click(function(event) {
event.preventDefault();
$(this).addClass("off").removeClass("on");
assignClicks();
});
};
assignClicks();
Hope this helps,
Pete
The click is bound to the element not the class.
Maybe you can attach the events to the elements and detect/toggle the elements classes:
$('li').click(function(event) {
event.preventDefault();
if( $(this).hasClass('on') ) {
$(this).removeClass('on');
}
else {
$(this).addClass('on');
$(this).siblings().removeClass('on');
}
});

How to check if there is already a click/event associated to an element

lets say I have
function trigger(){
$('a.pep').each(function(){
$('a.pep').click(function(){
console.log($(this).val());
});
});
}
function push(){
$('body').append('<a class="pep">hey mate i have no trigger yet</a>');
trigger(); //now i do but the others have duplicated trigger
}
$(document).ready(function(){
$('a.push').click(function(){
push();
});
});
So it seems that the click event is being applied twice/+ because the console.log is lauched more than once by click
How can i prevent this?
The problem is that you call $('a.pep').click() lots of times. (In fact, you bind as many click handlers as there are matching elements to each element. And then you do it again every time one of them is clicked.)
You should lever the DOM event bubbling model to handle this. jQuery helps you with the on method:
$(document.body).on('click', 'a.pep', function() {
console.log('element clicked');
$(document.body).append('<a class="pep">Click handlers handled automatically</a>');
});
See a working jsFiddle.
Note that I have removed the val call, because a elements can't have a value... Note also that the on method is introduced in jQuery 1.7; before that, use delegate:
$(document.body).delegate('a.pep', 'click', function() {
Small change to your trigger function is all you need. Just unbind the click event before binding to ensure that it is never added more than once. Also, you don't need to use each when binding events, it will add the event to each item automatically.
function trigger(){
$('a.pep').unbind('click').click(function() {
console.log($(this).val());
});
}
You can check using data('events') on any element if the required event is attached or not. For example to check if click event is attached or not try this.
if(!$('a.pep').data('events').click){
$('a.pep').click(function(){
console.log($(this).val());
});
}
you should use jQuery live here because you add DOM elements dynamicly and you want them to have the same click behaviour
function push(){
$('body').append('<a class="pep">hey mate i have no trigger yet</a>');
}
$(document).ready(function(){
$('a.push').click(function(){
push();
});
$('a.pep').live('click', function(){
console.log($(this).val());
});
});
Try:
if($('a.pep').data('events').click) {
//do something
}
i think if you use live() event you dont need to make function
$('a.pep').live('click', function(){
console.log($(this).val());
});

Categories