Is there an efficient way in jQuery to detect if anything other than a specific element (and it's children) has been clicked ??
<body>
<header></header>
<p>stuff<p>
<div class="floating-form">
<form>more stuff</form>
</div>
<footer></footer>
</body>
Whats the best way to remove the floating form, by listening for a click on anything other than the floating form?
Bind a click event listener to $(document) that removes div.floating-form.
Bind a click event to div.floating-form that stops event propogation.
The usual approach is to assign a click event handler to the specific element that does nothing other than stop event propagation. Then assign another click handler to the entire page (i.e. to the document) that removes the element in question. Clicks on the element won't propagate up to the document, so you'll get the functionality you want.
You can use the event.target attribute to determine what element triggered the click.
http://api.jquery.com/event.target/
$(document).click(function() {
//do something
});
$(".floating-form").click(function() {
return false;
});
Related
I'm trying to fire a click event on the innermost element in the HTML tree, but since there is a click even tied to its parent container, both events are fired, which is not what I need. I have fixed this before with stopPropagation(), but I can't seem to get it to work today.
jQuery('#parent li').click(function() {
jQuery(this).children('.contained').slideDown();
});
jQuery('.contained').click(function() {
Query(this).slideUp();
});
and let's say here is our HTML:
<ul id="parent">
<li>
click to show more
<p class="contained">click to hide</p>
</li>
</ul>
I believe this won't validate since it has a p contained within an li, but let's ignore that momentarily for simplicity's sake. How can I have the inner element slideUp() without have the parent click even trigger it to slideDown() immediately after?
return false to stop the bubbling:
jQuery('.contained').click(function() {
Query(this).slideUp();
return false;
});
Note that returning false also prevent the default behavior of the event.
Read more here.
Or use the event object's stopPropagation function:
jQuery('.contained').click(function(e) {
Query(this).slideUp();
e.stopPropagation();
});
The answer is to stop the propagation of the event. You can use stopPropagation and its twin, stopImmediatePropagation to do this or you can both stop propagation and prevent the default action by returning false from the handler. The stopPropagation method will prevent event bubbling, that is, the propagation of the event up the DOM tree. The stopImmdiatePropagation will do that but also prevent other handlers at the same level from firing. Returning false is equivalent to using stopPropagation and preventDefault on the event.
Two ways to do it, stop the propagation or combine the two click handlers and adjust code according to event.target
Target method:
jQuery('#parent li').click(function(event) {
var $tgt=jQuery(event.target)
if (!$tgt.is('.contained') ){
jQuery(this).children('.contained').slideDown();
}else{
$tgt.slideUp();
}
});
I have a 'li' that pops down when I click on a 'link' via jquery's 'click'.
Does anyone know of a clean way to do something along the lines of 'offclick'? As in, when I click off of the element, it would hide the pop down?
Thanks!
Matt
You would want to assign a click listener to the window and also assign the click listener to your link. Inside the link click listener, you'll want to stop the event propagation so it doesn't travel up the DOM tree and fire your window's click listener.
Something like this should do the trick:
$(window).click(function(){
$('li#my_li').slideUp();
});
$('a#my_link').click(function(event){
try
{
event.stopPropagation();
}
catch(err)
{
// IE does it this way
window.event.cancelBubble=true;
}
$('li#my_li').slideDown();
});
I guess you could look at blur, which is called when the element looses focus:
ref: http://api.jquery.com/blur/
You can use blur or focusout depending on your needs
<div id="menu">
<div class="menuitem-on" id="home">Home</div>
<div class="menuitem-off" id="mycart">My Cart</div>
<div class="menuitem-off" id="shop">Shop</div>
</div>
how do I assign click handlers to each of the children of menu with jquery?
$("#menu").delegate('div','click', function(){
//do your thing here
});
Handler is on parent, so only one. You can add more div without changing code.
Here is a fiddle page to show a couple of different selector options to get the click anywhere, or just the first level. Shows the use of the event target, currentTarget as well: http://jsfiddle.net/8GLZJ/
Update 3/18/2013 for 1.9.1+ jQuery use:
$("#menu").on('click','div', function(){
//do your thing here
});
You don't want to do that because:
You create a event handler for each children
If you dynamically add more elements, the handler won't work for them.
A better solution is to add a single event handler to the parent element and then do a different action based on the event.target property, that contains the clicked element.
This happens because of event bubbling and it's a cool feature you should take advantage of.
jQuery in particular abstracts this under what they call live events so you should go with those.
$("#menu div").click(function(){
// your code goes here
// $(this) give you the element that was clicked
});
Binding event to each one of element using click() or bind('click', ...) isn't a good solution, because in case if you have, lets say 50 items, you will have to bind 50 same handlers - browser has to register them all.
Better solution is to use feature called event delegation - and jQuery has special method for that - delegate(). So your code will look like this:
$('#menu').delegate('div', 'click', function() {
//code of your handler - 'this' refers to clicked element
});
There is an article with video showing difference between click, live and delegate in jQuery: NetTuts+.
Something like
$("#menu div").on('click', function(){
//alert('clicked');
});
Ok, simple question:
<div onclick="javascript:manualToggle(this)">
<span>Allowed to click</span>
<span>Not allowed to click</span>
<span>Allowed to click</span>
</div>
Without replicating the manualToggle on to the 2 spans that are allowed to click, how can I prevent the "Not allowed to click" span from firing it's parent div onclick event when it is clicked on?
Give the span an id an attach onclick event to it and use
A jQuery sample
$("#spn2").click(function(event){
event.stopPropagation();
});
event.stopPropagation(): Stops the bubbling of an event to parent elements, preventing any parent handlers from being notified of the event.
It would make sense to use a library but without you can try this (edited with an entire page to test):
<html><head></head>
<body>
<script type="text/javascript"><!--
function manualToggle(val)
{
alert(val.id);
}
--></script>
<div id="test" onclick="manualToggle(this);">
<span>Allowed to click</span>
<span onclick="event.cancelBubble=true;if (event.stopPropagation) event.stopPropagation();">Not allowed to click</span>
<span>Allowed to click</span>
</div>
</body>
</html>
You need an event handler (it's very easy to do this in something like jQuery) that catches clicks for the spans within the div and only fires the function if, for example, the span has/hasn't a particular class.
I just had the same issue and could not get jQuery to work so I used simple Javascript:
document.getElementById("your_span").addEventListener("click", (event) => {
event.stopPropagation();
});
That did the trick for me. Obviously you need to add the addEventListener to every Element you wanna apply this to. Since I do a lot of DOM manipulation this was not an issue for me.
Hope this helps anyone :)
with mootools you can use the method stopPropagation:
$('myChild').addEvent('click', function(ev){
ev.stopPropagation(); // this will prevent the event to bubble up, and fire the parent's click event.
});
see http://mootools.net/docs/core/Native/Event#Event:stopPropagation
also see this very similar question: How can I stop an onclick event from firing for parent element when child is clicked?
Possible solution: give the span's id's and check whether the clicked id is allowed to be clicked in your function
bad idea: you don't know which span is clicked since you call the function from your div...
<div onclick="manualToggle(this)">
<span>Allowed to click</span>
<span>Not allowed to click</span>
<span>Allowed to click</span>
</div>
<script>
function manualToggle(cur){
if(cur !== event.target) return false;
//CODE
}
</script>
Here we have set a click event on div tag,
and we are passing the current element(div) as parameter
inside the manualToggle function you have the element in params where you have set the event,
inside the function we have event (a global var object), where you can get the clicked element (event.target),
if the clicked element is not same(equal) to the element where we have set the event then do nothing.
there are some other methods are also available, use stopPropagation
https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation
I'm trying to make a site where the user can click on any element to edit it's CSS. I use the following to add the click function to all <li>, <div> and <ul>.
$('li,div,ul').click(function () {
alert(this.id);
});
The problem is if I click on a <li> element, then I get the alert for that and any element underneath it. (all the containers).
Is it possible to have only the top element trigger when clicked?
You want to stop event propagation, you do this in jQuery by calling the stopPropagation method on the event object.
$('li,div,ul').click(function (e) {
e.stopPropagation();
alert(this.id);
});
I believe you'd want to use stopPropagation(); inside the click function.
It sounds to me like you're looking for .stopPropagation(). Calling stopPropagation will prevent the event from "bubbling" up to parent containers.