I have a nested div like this
<div id="one">
<div id="two">
id two goes here
</div>
<div id="three">
id three goes here
</div>
<div id="four">
id four goes here
</div>
</div>
Now i want to handle click and doubleclick events on all divs except in div#four,
like this
$('#one').live('dblclick', function() {
my javascript code goes here
});
('#one').live('click', function() {
my javascript code goes here
});
How can i use the above script and exclude the last nested div #four.
Thanks
Like this:
$('#one, #one > div').not('#four').delegate('dblclick, click', function(){
// my javascript code goes here
});
EDIT: Based on further clarification, try this:
$('#one').bind('click dblclick', function( event ) {
var id = event.target.id;
if(id == "one" || id == "two" || id == "three") {
if(event.type == "click") {
// code for click event
} else {
// code for double click event
}
}
});
EDIT: Based on our conversation under another answer, it seems like you want the #one element to be clickable, but none of its child elements. If that is right, try this:
$('#one').click(function() {
// code to run when `one` is clicked.
}).children().click(function( event ) {
event.stopPropagation();
});
Now if there's any text in #one, the code for that element will fire, but it will not fire when you click any children of #one.
Let me know if that was what you wanted.
EDIT:
If you are saying that you will have a dynamic number of elements inside #one, and the last one will not get the event, then do this:
$('#one').delegate('div:not(:last-child)', 'click dblclick', function( event ) {
if(event.type == 'click') {
// do something for the click event
} else {
// do something for the double click event
}
});
Note that this assumes there will not be nested divs. Results may be unexpected if there are. Also, the #one element doesn't fire events. Only its children.
Original answer:
$('#one,#two,#three').bind('click', function(){
// code for click event
})
.bind('dblclick', function() {
// code for double click event
});
Or replace .bind with .live if you really need it.
I would use an additional class:
HTML:
<div id="one">
<div id="two" class="clickable">
id two goes here
</div>
<div id="three" class="clickable">
id three goes here
</div>
<div id="four">
id four goes here
</div>
</div>
JS:
('.clickable').live('click', function() {
});
Use not method, more on this here: How can I exclude these elements from a jQuery selection?
You must use $('#one') instead $('.one') aren't you?
$("div:not(#four)")
or
$("#one :not(#four)")
Will select any div that does not have the id="four" set. Basically the :not is what you are looking for. Anything in the :not parenthesis is negated for selection purposes.
http://api.jquery.com/not-selector/
An alternative is to attach a single click/double click handler to the parent which means no need for .live or anything, and in the handler ensure that you are receiving a click from an acceptable child with $(event.target).is(":not(#id)")
$("#one").click(function(event) {
if (this != event.target && $(event.target).is(':not(#four)')) {
// do work on event.target
}
});
// ...
Related
Given some simple HTML such this, where one element has an onclick function and it's child also has an onclick function:
<div style='background-color:blue;width:500px;height:500px;'
onclick='thing1();'>
<div style='background-color:red;width:100px;height:100px;'
onclick='thing2(57);'></div>
</div>
What would be the correct approach so that when a user clicks the child element, only the child's onclick is executed and not the parent's, but when the parent is clicked, it's onclick is still executed? I see that event.stopPropagation() would be the correct way to go, but since I'm passing an argument to the function thing2(), I can't seem to pass the event as well. For example:
function thing2(a,ev) {
// Do something with a
ev.stopPropagation();
}
Doesn't work, failing with the error TypeError: ev is undefined.
JQuery is fine.
The event is the first param.
function thing2(ev) {
var a = ev.target
ev.stopPropagation()
}
Secondly, it's best not to use onclick=. Instead, give your div classes or ids and do something like this:
<div class="thing-1" data-thingy="57">
<div class="thing-2" data-thingy="65"></div>
</div>
<script>
$('.thing-1').click(function (ev) {
ev.stopPropagation()
parseInt($(ev.target).data('thingy'), 10) // 57
})
$('.thing-2').click(function (ev) {
ev.stopPropagation()
parseInt($(ev.target).data('thingy'), 10) // 65
})
</script>
When you call a function on click, no event will be passed as argument and it somehow you can do that, that is not a Jquery object and that will not have stopPropagation property. SO you need to define jQuery click event handler for both divs, let's give them ids div1 and div2.
HTML
<div id="div1" style='background-color:blue;width:500px;height:500px;'>
<div id="div2" style='background-color:red;width:100px;height:100px;'></div>
</div>
In Javascript,
function thing2(ev) {
// Do something with a
console.log(ev);
alert('hi2');
ev.stopPropagation();
}
function thing1(ev) {
// Do something with a
alert('hi1');
}
$('#div1').click(thing1);
$('#div2').click(thing2);
I know this question might be repetitive as I have seen this solution: How do I detect a click outside an element?
I want to remove #main-element if I click outside the element, BUT, that element also has child elements inside. Meaning, if I click one of the child of #main-element, #main-element should not close
<div id="main-element">
<div class="test">1</div>
<div class="test">2</div>
<div class="test">3</div>
<div class="test">4</div>
</div>
I tried using this solution:
$('html').click(function(e){
if(e.target.id !== 'main-element') {
$("#main-element").removeClass("open").hide();
}
});
// For the trigger
$("#click-show").click(function(){
if($("#main-element").hasClass("open"))
{
$("#main-element").removeClass("open").hide();
}
else{
$("#main-element").addClass("open").show();
}
});
This might help:
DEMO
Use closest to loop through parents and classes to show/hide your element;
$('html').on('click', function(){
var mainElement = $('#main-element');
if($(this).closest(mainElement).length){
return;
}
mainElement.addClass('main-element-closed')
})
$('*').click(function(){
if($(this).has('#main-element') || $(this).parent().has('#main-element')){
// it will open here
}else{
//put your hide code
}
});
try to refer to function of jquery is HasClass('your child element class') with jquery.click(document)
Is there any solution to get object id while mouse entering it?
Something like this:
mouseenter(function () {
alert(ObjectName);
});
MORE:
Suppose that I have tens of DIV in my page and I want to change their color when mouse entering them, so I won't do that till i know the object ID, On the other side I can not set mouse enter function for any of them separately.
Suppose you have divs:
<div id="div1" class="list-item"></div>
<div id="div2" class="list-item"></div>
<div id="div3" class="list-item"></div>
With jQuery just do this to get the id:
$('.list-item').mouseenter(function (event) {
alert(event.target.id);
});
That said, you don't have to know the id to change the color because event.target is the div you want to change, I assume. So just do something like:
$('.list-item').mouseenter(function (event) {
$(event.target).css({backgroundColor: '#F00'});
});
$('.list-item').mouseleave(function (event) {
$(event.target).css({backgroundColor: ''});
});
if mouseenter is the jquery event handler then
$("<selector>").mouseenter(function(){
alert(this.id);
});
What is the best way to bind a functions to multiple div's?
$('#trigger1').change(function(){
// same code
});
$('#trigger3').change(function(){
// same code
});
Either use class (imo is class the best way)
<div class="trigger"></div>
<div class="trigger"></div>
$('.trigger').change(function(){
});
or do this
$('#trigger1,#trigger3').change(function(){
});
You can include multiple ids in the same function call:
$('#trigger1, #trigger3').change(function(){
// code goes here
});
Or you can give them the same class, e.g. triggerClass and then call it like such:
$('.triggerClass').change(function(){
// code goes here
});
add a common class name to those div
<div class="myClass" id="trigger1">
</div>
<div class="myClass" id="trigger2">
</div>
here is the script for it
$(".myClass").click(function(){
// your code
});
$('#trigger1, #trigger3').change(some_function);
Or:
$('#trigger1').add('#trigger3').change(some_function);
simply apply a same class to all elements then write
$('.classname').change(function(){
});
you could use
$('#trigger1, #trigger3').change(function(){
same code
});
to group the triggers
Add a common class:
<div class="rowTrigger">trigger 1</div>
<div class="rowTrigger">trigger 2</div>
Script
$(function(){
$("body").on("click", ".rowTrigger", function(e){
e.preventDefault();
var row = $(this); //row element
});
});
each "rowTrigger" will fire on the "click" handler, this can be changed to other or multiple events. See
http://api.jquery.com/on/ for more detail.
The scope of the events handled can be changed by changing "body" to "table" for example, so it will only fire when those 'div' rows from a table are clicked.
More simply it can be written as (firing for 'click' and 'hover' ... but you get the idea) :
$("div.rowTrigger").on("click hover", function(e){
e.preventDefault();
var row = $(this); //row element
//some extra code
});
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
});