I am using this code:
$('body').click(function() {
$('.form_wrapper').hide();
});
$('.form_wrapper').click(function(event){
event.stopPropagation();
});
And this HTML:
<div class="form_wrapper">
<a class="agree" href="javascript:;">I Agree</a>
<a class="disagree" href="javascript:;">Disagree</a>
</div>
The problem is that I have links inside the div
and when they no longer work when clicked.
$('html')
or $(document)
would be better than $('body')
Had the same problem, came up with this easy solution. It's even working recursive:
$(document).mouseup(function(e)
{
var container = $("YOUR CONTAINER SELECTOR");
// if the target of the click isn't the container nor a descendant of the container
if (!container.is(e.target) && container.has(e.target).length === 0)
{
container.hide();
}
});
You'd better go with something like this:
var mouse_is_inside = false;
$(document).ready(function()
{
$('.form_content').hover(function(){
mouse_is_inside=true;
}, function(){
mouse_is_inside=false;
});
$("body").mouseup(function(){
if(! mouse_is_inside) $('.form_wrapper').hide();
});
});
hover
event handler, which opens up many possibilities.
(function() { // ... code })();
I don't remember the name os this pattern, but it's super useful! All your declared variables will reside inside the function and won't pollute the global namespace.
This code detects any click event on the page and then hides the #CONTAINER
element if and only if the element clicked was neither the #CONTAINER
element nor one of its descendants.
$(document).on('click', function (e) {
if ($(e.target).closest("#CONTAINER").length === 0) {
$("#CONTAINER").hide();
}
});
You might want to check the target of the click event that fires for the body instead of relying on stopPropagation.
Something like:
$("body").click
(
function(e)
{
if(e.target.className !== "form_wrapper")
{
$(".form_wrapper").hide();
}
}
);
Also, the body element may not include the entire visual space shown in the browser. If you notice that your clicks are not registering, you may need to add the click handler for the HTML element instead.
e.stopPropagation();
if you have other click listener
form_wrapper
when you click one of its children, which isn't the desired behaviour. Use prc322's answer instead.
Check click area is not in the targeted element or in it's child
$(document).click(function (e) {
if ($(e.target).parents(".dropdown").length === 0) {
$(".dropdown").hide();
}
});
UPDATE:
jQuery stop propagation is the best solution
$(".button").click(function(e){
$(".dropdown").show();
e.stopPropagation();
});
$(".dropdown").click(function(e){
e.stopPropagation();
});
$(document).click(function(){
$(".dropdown").hide();
});
clicked
one. Otherwise, the stopPropagation
would make possible that multiple dropdowns are open at the same time.
$(".dropdown").click(function(e){ e.stopPropagation(); });
this is working fine for me ... thanks
$(document).click(function(event) {
if ( !$(event.target).hasClass('form_wrapper')) {
$(".form_wrapper").hide();
}
});
A solution without jQuery for the most popular answer:
document.addEventListener('mouseup', function (e) {
var container = document.getElementById('your container ID');
if (!container.contains(e.target)) {
container.style.display = 'none';
}
}.bind(this));
MDN: https://developer.mozilla.org/en/docs/Web/API/Node/contains
bind
there doesn't work. Could you fix the function to make it work?
Updated the solution to:
use mouseenter and mouseleave instead
of hover use live event binding
var mouseOverActiveElement = false;
$('.active').live('mouseenter', function(){
mouseOverActiveElement = true;
}).live('mouseleave', function(){
mouseOverActiveElement = false;
});
$("html").click(function(){
if (!mouseOverActiveElement) {
console.log('clicked outside active element');
}
});
.live
is now deprecated; use .on
instead.
Live demo with ESC functionality
Works on both Desktop and Mobile
var notH = 1,
$pop = $('.form_wrapper').hover(function(){ notH^=1; });
$(document).on('mousedown keydown', function( e ){
if(notH||e.which==27) $pop.hide();
});
If for some case you need to be sure that your element is really visible when you do clicks on the document: if($pop.is(':visible') && (notH||e.which==27)) $pop.hide();
Wouldn't something like this work?
$("body *").not(".form_wrapper").click(function() {
});
or
$("body *:not(.form_wrapper)").click(function() {
});
.form_wrapper
when you click its children (among other problems).
Instead of listening to every single click on the DOM to hide one specific element, you could set tabindex
to the parent <div>
and listen to the focusout
events.
Setting tabindex
will make sure that the blur
event is fired on the <div>
(normally it wouldn't).
So your HTML would look like:
<div class="form_wrapper" tabindex="0">
<a class="agree" href="javascript:;">I Agree</a>
<a class="disagree" href="javascript:;">Disagree</a>
</div>
And your JS:
$('.form_wrapper').on('focusout', function(event){
$('.form_wrapper').hide();
});
Even sleaker:
$("html").click(function(){
$(".wrapper:visible").hide();
});
.wrapper
no matter where you click on the page, which isn't what was asked for.
So many answers, must be a right of passage to have added one... I didn't see a current (jQuery 3.1.1) answers - so:
$(function() {
$('body').on('mouseup', function() {
$('#your-selector').hide();
});
});
And for Touch devices like IPAD and IPHONE we can use following code
$(document).on('touchstart', function (event) {
var container = $("YOUR CONTAINER SELECTOR");
if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) // ... nor a descendant of the container
{
container.hide();
}
});
(Just adding on to prc322's answer.)
In my case I'm using this code to hide a navigation menu that appears when the user clicks an appropriate tab. I found it was useful to add an extra condition, that the target of the click outside the container is not a link.
$(document).mouseup(function (e)
{
var container = $("YOUR CONTAINER SELECTOR");
if (!$("a").is(e.target) // if the target of the click isn't a link ...
&& !container.is(e.target) // ... or the container ...
&& container.has(e.target).length === 0) // ... or a descendant of the container
{
container.hide();
}
});
This is because some of the links on my site add new content to the page. If this new content is added at the same time that the navigation menu disappears it might be disorientating for the user.
Here's a jsfiddle I found on another thread, works with esc key also: http://jsfiddle.net/S5ftb/404
var button = $('#open')[0]
var el = $('#test')[0]
$(button).on('click', function(e) {
$(el).show()
e.stopPropagation()
})
$(document).on('click', function(e) {
if ($(e.target).closest(el).length === 0) {
$(el).hide()
}
})
$(document).on('keydown', function(e) {
if (e.keyCode === 27) {
$(el).hide()
}
})
Built off of prc322's awesome answer.
function hideContainerOnMouseClickOut(selector, callback) {
var args = Array.prototype.slice.call(arguments); // Save/convert arguments to array since we won't be able to access these within .on()
$(document).on("mouseup.clickOFF touchend.clickOFF", function (e) {
var container = $(selector);
if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) // ... nor a descendant of the container
{
container.hide();
$(document).off("mouseup.clickOFF touchend.clickOFF");
if (callback) callback.apply(this, args);
}
});
}
This adds a couple things...
Placed within a function with a callback with "unlimited" args Added a call to jquery's .off() paired with a event namespace to unbind the event from the document once it's been run. Included touchend for mobile functionality
I hope this helps someone!
if you have trouble with ios, mouseup is not working on apple device.
does mousedown /mouseup in jquery work for the ipad?
i use this:
$(document).bind('touchend', function(e) {
var container = $("YOURCONTAINER");
if (container.has(e.target).length === 0)
{
container.hide();
}
});
var n = 0;
$("#container").mouseenter(function() {
n = 0;
}).mouseleave(function() {
n = 1;
});
$("html").click(function(){
if (n == 1) {
alert("clickoutside");
}
});
$('body').click(function(event) {
if (!$(event.target).is('p'))
{
$("#e2ma-menu").hide();
}
});
p
is the element name. Where one can pass the id or class or element name also.
Copied from https://sdtuts.com/click-on-not-specified-element/
Live demo http://demos.sdtuts.com/click-on-specified-element
$(document).ready(function () {
var is_specified_clicked;
$(".specified_element").click(function () {
is_specified_clicked = true;
setTimeout(function () {
is_specified_clicked = false;
}, 200);
})
$("*").click(function () {
if (is_specified_clicked == true) {
//WRITE CODE HERE FOR CLICKED ON OTHER ELEMENTS
$(".event_result").text("you were clicked on specified element");
} else {
//WRITE CODE HERE FOR SPECIFIED ELEMENT CLICKED
$(".event_result").text("you were clicked not on specified element");
}
})
})
Return false if you click on .form_wrapper:
$('body').click(function() {
$('.form_wrapper').click(function(){
return false
});
$('.form_wrapper').hide();
});
//$('.form_wrapper').click(function(event){
// event.stopPropagation();
//});
Attach a click event to top level elements outside the form wrapper, for example:
$('#header, #content, #footer').click(function(){
$('.form_wrapper').hide();
});
This will also work on touch devices, just make sure you don't include a parent of .form_wrapper in your list of selectors.
var exclude_div = $("#ExcludedDiv");; $(document).click(function(e){ if( !exclude_div.is( e.target ) ) // if target div is not the one you want to exclude then add the class hidden $(".myDiv1").addClass("hidden"); });
$(document).ready(function() { $('.modal-container').on('click', function(e) { if(e.target == $(this)[0]) { $(this).removeClass('active'); // or hide() } }); }); .modal-container { display: none; justify-content: center; align-items: center; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0,0,0,0.5); z-index: 999; } .modal-container.active { display: flex; } .modal { width: 50%; height: auto; margin: 20px; padding: 20px; background-color: #fff; }
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ac varius purus. Ut consectetur viverra nibh nec maximus. Nam luctus ligula quis arcu accumsan euismod. Pellentesque imperdiet volutpat mi et cursus. Sed consectetur sed tellus ut finibus. Suspendisse porttitor laoreet lobortis. Nam ut blandit metus, ut interdum purus.
What you can do is bind a click event to the document that will hide the dropdown if something outside the dropdown is clicked, but won't hide it if something inside the dropdown is clicked, so your "show" event (or slidedown or whatever shows the dropdown)
$('.form_wrapper').show(function(){
$(document).bind('click', function (e) {
var clicked = $(e.target);
if (!clicked.parents().hasClass("class-of-dropdown-container")) {
$('.form_wrapper').hide();
}
});
});
Then when hiding it, unbind the click event
$(document).unbind('click');
i did it like this:
var close = true;
$(function () {
$('body').click (function(){
if(close){
div.hide();
}
close = true;
})
alleswasdenlayeronclicknichtschliessensoll.click( function () {
close = false;
});
});
dojo.query(document.body).connect('mouseup',function (e)
{
var obj = dojo.position(dojo.query('div#divselector')[0]);
if (!((e.clientX > obj.x && e.clientX <(obj.x+obj.w)) && (e.clientY > obj.y && e.clientY <(obj.y+obj.h))) ){
MyDive.Hide(id);
}
});
By using this code you can hide as many items as you want
var boxArray = ["first element's id","second element's id","nth element's id"];
window.addEventListener('mouseup', function(event){
for(var i=0; i < boxArray.length; i++){
var box = document.getElementById(boxArray[i]);
if(event.target != box && event.target.parentNode != box){
box.style.display = 'none';
}
}
})
According to the docs, .blur()
works for more than the <input>
tag. For example:
$('.form_wrapper').blur(function(){
$(this).hide();
});
div
s never blur - blur events can't even bubble to them from their children. Finally, even if the above weren't true, this would only work if you made sure that the .form_wrapper
was in focus before the user clicked off it.
Success story sharing
$("YOUR CONTAINER SELECTOR").unbind( 'click', clickDocument );
just beside.hide()
. Sodocument
don't keep listening for clicks.$(document).on("mouseup.hideDocClick", function () { ... });
in the function that opens the container, and$(document).off('.hideDocClick');
on hide function. Using namespaces I'm not removing other possiblemouseup
listeners attached to the document.