I have a JS global event handler which looks like this (this is temp code):
$(document).on('click', '.my-class, #box-in-my-class', function(e) {
console.log($(this), 'was clicked!');
if ($(this).is('my-class')) {
$(this).children('.dropdown').toggleClass('active');
}
if ($(this).is('#box-in-my-class')) {
$('#expander').toggleClass('active');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="my-class">
<div class="other-bit"></div>
<div class="dropdown">
<div id="box-in-my-class"></div>
</div>
</div>
<div id="expander"></div>
(the .active class added makes the div bigger - through css).
However, in running this, when I click the #box-in-my-class, I get this in the console:
#box-in-my-class was clicked!
.my-class was clicked!
which toggles the dropdown (closing it).
How do I set it so that when you click the child of an element it does not bubble/propagate/etc. so that I can click the #box-in-my-class w/o running .my-class
Because your event bubbles. In the code you must call e.stopPropagation(); And also you have some missed ')'.
$(document).on('click', '.my-class, #box-in-my-class', function(e) {
e.stopPropagation();
console.log(e.target, 'was clicked!');
if ($(this).is('my-class')) {
$(this).children('.dropdown').toggleClass('active');
}
if ($(this).is('#box-in-my-class')) {
$('#expander').toggleClass('active');
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="my-class">
<div class="other-bit"></div>
<div class="dropdown">
<div id="box-in-my-class">Test 1</div>
</div>
</div>
<div id="expander">Test 2</div>
For more see event bubbling
and e.stopPropagation()
try the following
$(document).on('click', '.my-class, #box-in-my-class', function(e) {
if ($(this).is('.my-class') && $(e.target).is(':not(#box-in-my-class')) {//check if the clicked element is not box-in-my-class
console.log($(this), 'was clicked!');
$(this).children('.dropdown').toggleClass('active');
}
if ($(this).is('#box-in-my-class')) {
$('#expander').toggleClass('active');
}
}
demo:http://jsfiddle.net/0yvuzm0c/
I think you shouldn't use 2 if class when you only need one response.
If I were you, I would write my JS function like this:
if ($(this).is('#box-in-my-class') {
$('#expander').toggleClass('active');
return;
}else if ($(this).is('my-class') {
$(this).children('.dropdown').toggleClass('active');
return;
}
I will check this $('#box-in-my-class') first due to the reason that $('#box-in-my-class') is the child of $(.'my-class').
In this case, if it detected $('#box-in-my-class') is clicked, it will stop the loop. instead of checking $(.'my-class') too.
You may study http://www.w3schools.com/js/js_if_else.asp to be more familiar with if, else, else if loop.
Related
I have a <div class="stock"></div>wrapped around :
<div class="stockAdd"></div>
<div class="stockRemove"></div>
<div class="stockInput"></div>
I want to prevent a click inside my .stock to trigger a function. For now i have the following :
if ($(event.target).is('.stockInput') || $(event.target).is('.stockAdd') || $(event.target).is('.stockRemove')) {
console.log("Ajout stock");
return
}
Isn't there a better way to select thos three divs ? The $(event.target).is('.stock') don't get the job done when i click my nested divs.
Thanks
If I understand you correctly, you want to catch click events on .stockAdd, .stockRemove, and .stockInput, but not on other elements within .stock itself, is that correct?
If so, a delegated event can take care of that without any need to manually check the event target:
$('.stock').on('click', '.stockAdd, .stockRemove, .stockInput', function() {
alert("Clicked");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="stock">
<div class="stockAdd">stockAdd</div>
<div class="stockRemove">stockRemove</div>
<div class="stockInput">stockInput</div>
<div>No event</div>
</div>
I would strongly recommend against depending on event.target here; it's too fragile. Any HTML tags nested inside your desired targets would break things:
$('.stock').on('click', function(event) {
if (event.target.className=="stockAll") {
alert("clicked");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="stock">
<div class="stockAll">
This <b> will not work if someone clicks in the bold area</b> but works outside
</div>
</div>
You can add a separate class to all of them like .stock-inner and then grab them all with $('.stock-inner') or you can use a $("div[class^='stock-inner']) - this will grab the parent .stock div...
Also, to reject a click event within the handler you're gunna want to use e.preventDefault() where e is the event object.
the reason it doesn't work well on nested divs is they pass the conditional if in your example, to make it stricter you could add div to selector:
if ($(event.target).is('div.stockInput') || $(event.target).is('div.stockAdd') || $(event.target).is('div.stockRemove'))
You can attach the event on .stock and then filter using the event.target.
HTML
<div class="stock" style="border: 10px solid #000;">
<div class="stockAdd">Add</div>
<div class="stockRemove">Remove</div>
<div class="stockInput">Input</div>
</div>
JavaScript
$('.stock').on('click', function(e) {
if( e.target.className !== 'stock' ) {
console.log(e.target.className);
}
});
jsfiddle
I want to run a javascript function everytime a user clicks anywhere on the page (div "maincontent") EXCEPT on any of the two buttons (div "btnNew" and "btnRegister"). How can I do that? My first approach doesn't work.
<div id="mainContent" class="content" onclick="hidePopUps(document.this)">
[...]
<div id="btnNew" class="btn-welcome" onclick="showRegister()">New user</div>
<div id="btnRegister" class="btn-welcome" onclick="showLogin()">Existing user</div>
[...]
</div>
function hidePopUps(element) {
if(element == $("#mainContent")) {
hideLogin();
hideRegister();
}
}
You can do this with jQuery and the :not() selector:
$(":not(body):not(html):not(#btnNew):not(#btnRegister)").click(function() {
// the :not(body) and :not(html) are to prevent it
// from setting off additional event listeners because
// everything is on top of the html and body tags
// ... handler here
});
This should select everything but those two buttons.
See a working example at JSFiddle.net.
To make things work the way you want I would:
change your onlick events:
a. you don't need hidePopUps(document.this), just hidePopUps(this)
b. in showRegister() and showLogin() put 'event' variable inside brackets to pass it to these functions to avoid bubbling
prevent bubbling when buttons are clicked in called functions
use id to check if container was clicked: should read as if(element.id == 'mainContent') { instead of if(element == $("#mainContent")) {
So your code could look like:
<div id="mainContent" class="content" onclick="hidePopUps(this)">
<div>some content before</div>
<div id="btnNew" class="btn-welcome" onclick="showRegister(event)">New user</div>
<div id="btnRegister" class="btn-welcome" onclick="showLogin(event)">Existing user</div>
<div>some content after</div>
</div>
function showRegister(event) {
event.stopPropagation();
...
}
function showLogin(event) {
event.stopPropagation();
...
}
function hidePopUps(element) {
if(element.id == 'mainContent') {
hideLogin();
hideRegister();
}
}
Check out this fiddle: JSFiddle
I have this code
<style>
.Parent {width:500px;height:500px;background:#000}
.Parent .Child {width:250px;height:250px;background:#F00}
</style>
<div class="Parent">
<div class="child"></div>
</div>
<script>
$(document).ready(function() {
$('.Parent').click(function () {
$(this).hide()
});
/*
But if i click on <div class="Child"></div> ,
<div class="Parent"></div> won't get hidden .
*/
});
</script>
I want my code to hide'.parent',
When I click on areas in .Parent witch doesn't include .Child elementand if the areas I click was included in '.child' area , it don't do anything .
so what would u guys suggest ?
Simply make of event.stopPropagation(); to stop event of child from propagating to parent.
So script becomes:
$('.Parent').click(function () {
$(this).hide();
});
$('.child').click(function (e) {
e.stopPropagation();
});
See the fiddle: "http://jsfiddle.net/sftknxeo/1/"
just do this:
$('.Parent, .child').click(function(e) {
if ($(this).hasClass('child')) {
return false;
}
$(this).hide();
});
$('.Parent, .child').click(function(e) {
if ($(this).hasClass('child')) {
return false;
}
$(this).hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='Parent' style='width:auto; padding:50px; border:red solid 1px;'>
<div class='child' style='width:200px; height:200px;border:green solid 1px;'>
child
</div>
</div>
You can use the event's target to determine what you have clicked on. This way you can also assign an event to happen if you have clicked on the child. (If need be.)
$('.Parent').click(function(e){
if(e.target == this){
$(this).hide()
}
});
DEMO
Quick and dirty version would be simply to add another event handler. Add a click handler to child that hides parent. Then if you click on parent, it hides itself, and if you click on child, it hides parent.
$('.child').click(function (e) {
$('.parent').hide();
});
Not the most elegant solution, sure, but it's quick and easy and should get the job done.
$('.Parent').click(function () {
$(this).css("visibility", "hidden");
$(".Parent" ).children().css("visibility", "visible");
});
If you just want to hide parent then it will do the needful.
Check for the clicked element by looking at the target property of the event object. Here is something you might want to do:
$(function () {
$('.Parent').click(function (e) {
if ($(e.target).hasClass("child")) {
return false;
}
$(this).hide();
});
});
$('.parent').click(function(e) {
if ($(this).hasClass('child')) {
return false;
}
$(this).hide();
});
I have an app I'm developing and I need a onclick() event to be fired when a <div> is clicked.
So in other words,
<div id="panda"></div>
$("#panda").click(function () {
console.log("some text");
});
So this statement works but now lets say I have,
<div id="panda">
<lots of children>
<div id="koala">
</div>
</lots of children>
</div>
$("#koala").click(function () {
console.log("doesnt work");
});
Now you see for the life of me I can't get koala to be clickable. The click event on parents works fine, and click evens for some empty divs I use as buttons work fine, but for some reason I cant get I filled child <div> to be clickable.
Any ideas what the case could be?
I tried this,
$('#panda').click(function(e){
if ($(e.target).is('#koala'))
{
console.log("koala");
}
});
But it just logs every click on the parent.
One option is to listen to the div children for panda.
$("#panda").on('click','div',function() {
console.log($(this).text()+' '+$(this).attr('id'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="panda">
<div id="koala">
koala
</div>
<div id="bear">
bear
</div>
</div>
Try making the selector '#panda #koala' like this
$("#panda #koala").click(function () {
console.log("koala");
});
Here is an example,
<div id="panda">Panda
<div id="koala">Koala</div>
</div>
$("#panda").on('click', '#koala', function () {
alert("koala!!!");
});
Here is a Fiddle
Inside that I have other child divs. Those have child divs too.
<div class="parent">
<div class="child_1">//children elements</div>
<div class="child_1">//children elements</div>
<div class="child_1">//children elements</div>
<div class="child_1">//children elements</div>
</div>
I want to add a click event that fires when I click any element inside parent div, including parent div, excluding child_1 div and its descendants.
Currently I tried with
jQuery(".parent").not(".child_1").click(function(event) {
});
But the click event works when I click on child_1 div and it's descendants.
What is the problem here? please help.
UPDATE
here i have another click event for child_1
jQuery(".child_1").click(function(event) {
});
You should do it like this.
$('.parent').on('click', function () {
// do your stuff here
}).find('.child_1').on('click', function (e) {
e.stopPropagation();
});
Here is a fiddle http://jsfiddle.net/BbX7D/1/
You still have to catch the click event on the elements that you want to exclude, otherwise the click will just bubble up to the .parent element.
Use the closest method to check if the clicked element is, or is a child of, an element with the class .child_1. Use stopPropagation to keep the event from bubbling:
$('.parent,.parent *').click(function(e){
if ($(this).closest('.child_1').length > 0) {
alert('in child_1');
} else {
alert('not in child_1');
}
e.stopPropagation();
});
Demo: http://jsfiddle.net/Guffa/tETCQ/
I think it should be
jQuery(".parent, .parent *").not(".child_1").click(function(event) {
});
Try this (fiddle):
(edit + updated fiddle)
I spotted a flaw. This version checks if the clicked element is or is inside an element which has the class 'exclude':
<div class="parent">
<div class="child_1 exclude">//children elements</div>
<div class="child_1">//children elements</div>
<div class="child_1">//children elements</div>
<div class="child_1">//children elements</div>
</div>
jQuery(".parent").click(function(event)
{
if ($(event.target).closest('.exclude').length>0) return false;
alert('hi');
});
a bit of an old question, but figured i'd throw out my resolution in case it helps anyone else.
this is pretty much what i did. this example uses your markup:
$('.parent').on('click', function(e) {
var $target = $(e.target);
if (!$target.parents('.child_1').length && !$target.hasClass('child_1')) {
// do what you need on the parent's click event
// add 'e.preventDefault()' here if you need
}
// no need to prevent default or stop propagation here
// this will allow click events on child elements to work
});