So I have the following html
<li clas='k-item'>
<input type='checkbox'>
<span>ABC</span>
</li>
Is there any way I can bind click to only input and disable for span and li?
This is what I tried, but it doesn't seem to work
$('.k-item').on('click', function (e) {
$(this).unbind('click');
if ($(e.target).is('input')) {
$('input').bind('click');
}
});
I do not have much experience with jquery
You need to use:
$('.k-item input').click(function(){
//modify the rest handler code...
});
Update: if click is defined for li, and you don't want that to be triggered on child span then you will need to stop event propagation.
$('.k-item span').click(function(e){
e.stopPropagation();//do not trigger parent click on child span
});
Why not just target the input to begin with? You can then use e.stopPropagation() to prevent the LI from getting the click event (which is I gather your aim):
$('.k-item input').click(function (e) {
// Stop the LI from firing a click event
e.stopPropagation();
// input is clicked
});
You need only this:
$('.k-item').on('click', function (e) {
if ($(e.target).is('input')) {// or event.target.type
//do stuff
}
});
Just select the desired element and apply the event listener:
$('.k-item > input').on('click', function() { // ... });
Related
I am trying to remove ul element on click of body element and ignore if the click target is on the ul element itself otherwise click execute and ul get removed.
Every thing works well but a programmatic click from another js removes ul after its execution which is a problem.The ul should be removed by the user interaction only. Please help me to solve this conflict.
<div class="search-input">
<ul>
<li><a href='#'>1</a></li>
<li><a href='#'>2</a></li>
</ul>
</div>
$(document).on('click','body', function(e) {
if(!$(e.target).closest(".search-input").find('ul').length > 0) {
$('.search-input ul').remove();
}
});
// programmatic click trigger
$(hotspot).trigger("click", true);
The above programmatic click event execute the body click event which is not required.
Put this condition.
is_click = true;
$(document).on('click','body', function(e) {
if(is_click){
if(!$(e.target).closest(".search-input").find('ul').length > 0) {
$('.search-input ul').remove();
}
if(!$(e.target).closest(".input-search").find('ul').length > 0) {
$('.input-search ul').remove();
}
}
});
and for programmatic click trigger
is_click = false;
$(hotspot).trigger("click", true);
is_click = true;
I have a button inside a division.Both have separate onclick listeners.But since button is a part of the division,the event attached to button is also triggered when clicked.Is there a way to remove it?
i tried :not / .not.it dint work.
<div id="divson">
<button id="btn"></button>
</div>
$('#divson').not('#btn').click(function sayHello() {
alert('Helo!');
});
$('#btn').click(function sayJello() {
alert('Jelo!');
});
http://jsfiddle.net/gw3LqrcL/
Just return false; in your handler to stop the event propagation: http://jsfiddle.net/gw3LqrcL/1/
Use stopPropagation on the event passed in to the handler on #btn to stop the event bubbling to the parent element:
$('#divson').click(function () {
alert('Helo!');
});
$('#btn').click(function (e) {
e.stopPropagation();
alert('Jelo!');
});
Updated fiddle
Here's a fiddle illustrating the problem. I am adding a jQuery one binding on the click of one element to the 'html' element. I am not expecting the 'one' event handler to fire until the next click, but it fires on the click that adds the binding. This seems to not be a problem if it is a more specific element that the 'one' event handler is added to, but it happens when I use 'html' or 'body' as the element, which is what I want to do.
This doesn't make sense to me, I'd think the first click would add the one for the next click and it wouldn't fire on the click on the link.
By the way, my actual problem could probably be solved in a better way, but I came across this and was curious why it didn't work as I expected.
Code:
html:
<div id='hello'>hello</div>
<a class="title" href="#">this example</a> is a test
js:
$(function() {
$('a.title').click(function() {
var htmlClickBind = function (e) {
console.log('clicked on html, e.target = ' + e.target);
console.log(e.target == '');
if (!$(e.target).is('a') ) {
console.log('cleared click event');
}
else {
$('html').one('click', htmlClickBind);
}
};
$('html').one('click', htmlClickBind);
});
});
The click event on the a.target element bubbles up to the html element, where your (just-added) handler sees it.
To prevent this, use event.stopPropgation in your a.target click handler (or return false, which does stopPropagation and preventDefault).
Updated code (see the comments): Live copy
$(function() {
// Accept the event arg ----v
$('a.title').click(function(e) {
// Stop propagation
e.stopPropagation();
var htmlClickBind = function (e) {
console.log('clicked on html, e.target = ' + e.target);
console.log(e.target == '');
if (!$(e.target).is('a') ) {
console.log('cleared click event');
}
else {
$('html').one('click', htmlClickBind);
}
};
$('html').one('click', htmlClickBind);
});
});
I have the following function to open an overlay menu:
$('.context-switch').click(function() {
$(".context-switch-menu").toggle();
});
To hide the menu, I would like the user to be able to click on any area outside ".context-switch-menu"
I am trying with :not() but with no success..
$('body').click(function(e) {
if ($(e.target).hasClass('context-switch')) {
return;
}
$(".context-switch-menu").hide();
});
$('.context-switch').click(function() {
$(".context-switch-menu").toggle();
return false;
});
The reason this can be difficult is because of event bubbling.
You can try something like this:
$('.context-switch').click(function(e) {
e.stopPropagation();
$(".context-switch-menu").toggle();
});
$(".context-switch-menu").click(function(e){
e.stopPropagation();
});
$("body").click(function(e){
$(".context-switch-menu").hide();
});
The e.stopPropagation() prevents the click event from bubbling to the body handlers. Without it, any click to .context-switch or .context-switch-menu would also trigger the body event handler, which you don't want, as it would nullify the effect of the .context-switch click half the time. (ie, if the state is hidden, and then you click to show, the event would bubble and trigger the body handler that would then hide the .context-switch-menu again.)
Without testing, would something like this work?:
$('.context-switch').click(function() {
$(".context-switch-menu").show();
});
$(document).click(function() {
$(".context-switch-menu").hide();
});
Instead of using document, 'html' or 'body' may work as well.
$(document).on('click', function(e) {
if (e.target.className !='context-switch-menu') {
$(".context-switch-menu").hide();
}
});
Just an idea here, based on what what others have suggested in the past:
$(document).click(function(e){
//this should give you the clicked element's id attribute
var elem = $(e.target).attr('classname');
if(elem !== 'context-switch-menu'){
$('.context-switch-menu').slideUp('slow');
//or however you want to hide it
}
});
try this, we don't want to call a function when you clicked on the element itself, and not when we click inside the element. That's why we need 2 checks.
You want to use e.target which is the element you clicked.
$("html").click(function(e){
if( !$(e.target).is(".context-switch-menu") &&
$(e.target).closest(".context-switch-menu").length == 0
)
{
alert("CLICKED OUTSIDE");
}
});
Live fiddle: http://jsfiddle.net/Xc25K/1/
I can't stop the stupid thing from firing off an event when hovering over the children of item.
I only want the event to fire via the div.item element, not the div.itemChild. This is driving me nuts please help.
event.stopPropigation does not work. nor does if(!$(event.source).is('itemChild')), for some reason is() alway returns false.
HTML
<div id="items">
<div class="item">
<div class="itemChild">
</div>
<div class="itemChild">
</div>
</div>
</div>
JS
//on hover event for each post
$('div.item', '#items').live('mouseover mouseout', function(event){
if (event.type == 'mouseover'){
//fire mouseover handler
}
else{
//fire mouseout handler
}
});
Is there a way to stop live from firing when hovering the children of div.item?
By the way the children of div.item cover it completely.
Basically I want this to act like .hover() but bind to things loaded via ajax.
It's not binding to the children. It's bubbling up to the parent.
Also, your syntax isn't correct. This:
$("div.item", "div.items")...
is saying "find me all the divs with class item that are descendants of divs with class of items. But you have no such divs (with class items). You have a div with an ID of items.
Combining all this try:
$("#items div").live("mouseover mouseout", function(event) {
if ($(event.source).hasClass("itemChild")) {
return false;
} else if (event.type == "mouseover") {
...
} else {
...
}
});
Or, alternatively:
$("#items > div.item").live("mouseover mouseout", function(event) {
if (!($this).is("div.item")) {
return false;
}
...
});
Basically, there are many ways to skin this cat but like I said in the first sentence, you have to understand that events bubble up until the handlers stop propagation, either directly (by calling event.stopPropagation() or by returning false from the event handler, which is equivalent to event.stopPropagation(); event.preventDefault();).
Also, if you're doing mouseenter and mouseout you might as well just use the hover() event that does both of those:
$("#items > div.item").live("hover", function(event) {
// mouseenter
}, function(event) {
// mouseout
});