web-dev-qa-db-fra.com

Utilisez jQuery pour masquer une DIV lorsque l'utilisateur clique en dehors de celle-ci

J'utilise ce code:

$('body').click(function() {
   $('.form_wrapper').hide();
});

$('.form_wrapper').click(function(event){
   event.stopPropagation();
});

Et ce HTML:

<div class="form_wrapper">
   <a class="agree" href="javascript:;">I Agree</a>
   <a class="disagree" href="javascript:;">Disagree</a>
</div>

Le problème est que j'ai des liens dans la DIV et quand ils ne fonctionnent plus lorsqu'on clique dessus.

926

Avait le même problème, est venu avec cette solution facile. Cela fonctionne même récursif:

$(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();
    }
});
2411
user659025

Vous feriez mieux d'aller avec quelque chose comme ça:

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();
    });
});
199
Makram Saleh

Ce code détecte tout événement de clic sur la page, puis masque l'élément #CONTAINER si et seulement si l'élément sur lequel l'utilisateur a cliqué n'est ni l'élément #CONTAINER ni l'un de ses descendants.

$(document).on('click', function (e) {
    if ($(e.target).closest("#CONTAINER").length === 0) {
        $("#CONTAINER").hide();
    }
});
75
Case

Vous voudrez peut-être vérifier la cible de l'événement click qui se déclenche pour le corps au lieu de s'appuyer sur stopPropagation.

Quelque chose comme:

$("body").click
(
  function(e)
  {
    if(e.target.className !== "form_wrapper")
    {
      $(".form_wrapper").hide();
    }
  }
);

De plus, l'élément body peut ne pas inclure tout l'espace visuel affiché dans le navigateur. Si vous remarquez que vos clics ne s'enregistrent pas, vous devrez peut-être ajouter le gestionnaire de clics pour l'élément HTML.

72
David Andres

Live DEMO

Vérifier que la zone de clic ne se trouve pas dans l'élément ciblé ou dans son enfant

$(document).click(function (e) {
    if ($(e.target).parents(".dropdown").length === 0) {
        $(".dropdown").hide();
    }
});

UPDATE:

jQuery stop propagation est la meilleure solution

Live DEMO

$(".button").click(function(e){
    $(".dropdown").show();
     e.stopPropagation();
});

$(".dropdown").click(function(e){
    e.stopPropagation();
});

$(document).click(function(){
    $(".dropdown").hide();
});
31
Salim
$(document).click(function(event) {
    if ( !$(event.target).hasClass('form_wrapper')) {
         $(".form_wrapper").hide();
    }
});
18
meder omuraliev

Mise à jour de la solution pour:

  • utilisez mouseenter et mouseleave à la place
  • de survol utiliser la liaison d'événement en direct

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');
    }
});
16
benvds

Une solution sans jQuery pour la réponse la plus populaire :

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

12
Martin Vseticka

Démo en direct avec ESC fonctionnalité

Fonctionne à la fois Desktop et Mobile

var notH = 1,
    $pop = $('.form_wrapper').hover(function(){ notH^=1; });

$(document).on('mousedown keydown', function( e ){
  if(notH||e.which==27) $pop.hide();
});

Si, dans certains cas, vous devez être sûr que votre élément est vraiment visible lorsque vous cliquez sur le document: if($pop.is(':visible') && (notH||e.which==27)) $pop.hide();

8
Roko C. Buljan

Quelque chose ne va pas comme ça?

$("body *").not(".form_wrapper").click(function() {

});

ou

$("body *:not(.form_wrapper)").click(function() {

});
6
MRVDOG

Au lieu d'écouter chaque clic sur le DOM pour masquer un élément spécifique, vous pouvez définir tabindex sur le parent <div> et écouter les événements focusout.

Le réglage de tabindex permet de s'assurer que l'événement blur est déclenché sur le <div> (normalement, ce ne serait pas le cas).

Donc, votre HTML ressemblerait à ceci:

<div class="form_wrapper" tabindex="0">
    <a class="agree" href="javascript:;">I Agree</a>
    <a class="disagree" href="javascript:;">Disagree</a>
</div>

Et votre JS:

$('.form_wrapper').on('focusout', function(event){
    $('.form_wrapper').hide();
});
5
Oscar

Encore sleaker:

$("html").click(function(){ 
    $(".wrapper:visible").hide();
});
4
Olivenbaum

Construit à partir de la réponse impressionnante de prc322.

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);
    }
  });
}

Cela ajoute quelques choses ...

  1. Placé dans une fonction avec un rappel avec des arguments "unlimited"
  2. Ajout d'un appel à .off () associé à un espace de nom d'événement pour dissocier l'événement du document une fois qu'il a été exécuté.
  3. Touchend inclus pour la fonctionnalité mobile

J'espère que ça aidera quelqu'un!

4
WiseOlMan

Et pour les appareils tactiles comme IPAD et IPHONE, nous pouvons utiliser le code suivant

$(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();
    }
});
4
Code Spy

Voici un jsfiddle que j'ai trouvé sur un autre thread, fonctionne avec la touche echa aussi: 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()
      }
    })
4
djv
var n = 0;
$("#container").mouseenter(function() {
n = 0;

}).mouseleave(function() {
n = 1;
});

$("html").click(function(){ 
if (n == 1) {
alert("clickoutside");
}
});
2
Gary

Attachez un événement de clic aux éléments de niveau supérieur en dehors du wrapper de formulaire, par exemple:

$('#header, #content, #footer').click(function(){
    $('.form_wrapper').hide();
});

Cela fonctionnera également sur les appareils tactiles. Assurez-vous de ne pas inclure un parent de .form_wrapper dans votre liste de sélecteurs.

2
ThornberryPie
$(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;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="modal-container active">
        <div class="modal">
                <p>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.</p>
        </div>
</div>
2
RustBeard
 $('body').click(function(event) {
    if (!$(event.target).is('p'))
    {
        $("#e2ma-menu").hide();
    }
});

p est le nom de l'élément. Où l'on peut également passer l'identifiant ou le nom de la classe ou de l'élément.

2
Abhishek

Renvoie false si vous cliquez sur .form_wrapper:

$('body').click(function() {
  $('.form_wrapper').click(function(){
  return false
});
   $('.form_wrapper').hide();
});

//$('.form_wrapper').click(function(event){
//   event.stopPropagation();
//});
2
bogo

(Ajoutant simplement à la réponse de prc322.)

Dans mon cas, j'utilise ce code pour masquer un menu de navigation qui apparaît lorsque l'utilisateur clique sur un onglet approprié. J'ai trouvé utile d'ajouter une condition supplémentaire, à savoir que la cible du clic en dehors du conteneur est non un lien.

$(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();
    }
});

En effet, certains liens sur mon site ajoutent un nouveau contenu à la page. Si ce nouveau contenu est ajouté en même temps que le menu de navigation disparaît, cela peut désorienter l'utilisateur.

2
shngrdnr

Copié à partir de https://sdtuts.com/click-on-not-specified-element/

Démo en direct 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");
        }
    })
})
2
user3151197

si vous rencontrez des problèmes avec iOS, la souris ne fonctionne pas sur le périphérique Apple.

mousedown/mouseup dans jquery fonctionne-t-il pour l'ipad?

j'utilise ceci:

$(document).bind('touchend', function(e) {
        var container = $("YOURCONTAINER");

          if (container.has(e.target).length === 0)
          {
              container.hide();
          }
      });
2
user2271066

je l'ai fait comme ça:

var close = true;

$(function () {

    $('body').click (function(){

        if(close){
            div.hide();
        }
        close = true;
    })


alleswasdenlayeronclicknichtschliessensoll.click( function () {   
        close = false;
    });

});
1
user2822517
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);
    }
});
1
Abed Yaseen
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");  

}); 

VIOLON

1
SharmaPattar

Tant de réponses doivent être un droit de passage pour en avoir ajouté une ... Je n'ai pas vu de réponses actuelles (jQuery 3.1.1) - donc:

$(function() {
    $('body').on('mouseup', function() {
        $('#your-selector').hide();
    });
});
1
zak

En utilisant ce code, vous pouvez masquer autant d'éléments que vous le souhaitez.

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';
    }
   }
})
1
Mahdi Younesi

Selon la documentation , .blur() fonctionne pour plus que la balise <input>. Par exemple:

$('.form_wrapper').blur(function(){
   $(this).hide();
});
0
Bizley

Basculer pour les appareils réguliers et tactiles

J'ai lu certaines réponses ici il y a quelque temps et créé du code que j'utilise pour les div qui fonctionnent comme des bulles contextuelles.

$('#openPopupBubble').click(function(){
    $('#popupBubble').toggle();

    if($('#popupBubble').css('display') === 'block'){
        $(document).bind('mousedown touchstart', function(e){
            if($('#openPopupBubble').is(e.target) || $('#openPopupBubble').find('*').is(e.target)){
                $(this).unbind(e);
            } 
            else if(!$('#popupBubble').find('*').is(e.target)){
                $('#popupBubble').hide();
                $(this).unbind(e);
            }
        });
    }
});

Vous pouvez également rendre cela plus abstrait en utilisant des classes et sélectionner la bulle contextuelle appropriée en fonction du bouton qui a déclenché l'événement click.

$('body').on('click', '.openPopupBubble', function(){
    $(this).next('.popupBubble').toggle();

    if($(this).next('.popupBubble').css('display') === 'block'){
        $(document).bind('mousedown touchstart', function(e){
            if($(this).is(e.target) || $(this).find('*').is(e.target)){
                $(this).unbind(e);
            } 
            else if(!$(this).next('.popupBubble').find('*').is(e.target)){
                $(this).next('.popupBubble').hide();
                $(this).unbind(e);
            }
        });
    }
});
0
Sceptic

Je travaillais sur un champ de recherche qui affiche la saisie semi-automatique en fonction des mots-clés traités. Lorsque je ne veux pas cliquer sur une option, je vais utiliser le code ci-dessous pour masquer la liste traitée et cela fonctionne.

$(document).click(function() {
 $('#suggestion-box').html("");
});

Suggestion-box est mon conteneur autocomplete où je montre les valeurs.

0
Vivek
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js">
</script>
<script>
$(document).ready(function(){
  $("#hide").click(function(){
    $("p").hide();
  });
  $("#show").click(function(){
    $("p").show();
  });
});
</script>
</head>
<body>
<p>If you click on the "Hide" button, I will disappear.</p>
<button id="hide">Hide</button>
<button id="show">Show</button>
</body>
</html>
0
Bhushan wagh

Ce que vous pouvez faire est de lier un événement de clic au document qui masquera le menu déroulant si vous cliquez sur quelque chose en dehors du menu déroulant, mais ne le cachera pas si vous cliquez sur un élément du menu déroulant, de sorte que votre événement "show" montre la liste déroulante)

    $('.form_wrapper').show(function(){

        $(document).bind('click', function (e) {
            var clicked = $(e.target);
            if (!clicked.parents().hasClass("class-of-dropdown-container")) {
                 $('.form_wrapper').hide();
            }
        });

    });

Puis, lorsque vous le cachez, dissociez l'événement click

$(document).unbind('click');
0
jeffsaracco

Cette solution devrait bien fonctionner, c'est simple:

jQuery(document).ready(function($) {
    jQuery(document).click(function(event) {
        if(typeof  jQuery(event.target).attr("class") != "undefined") {
            var classnottobeclickforclose = ['donotcountmeforclickclass1', 'donotcountmeforclickclass2','donotcountmeforclickclass3'];
            var arresult = jQuery.inArray(jQuery(event.target).attr("class"), classnottobeclickforclose);
            if (arresult < 0) {
                jQuery(".popup").hide();
            }
        }
    });
});

Dans Changement de code ci-dessus, donotcountmeforclickclass1, donotcountmeforclickclass2, etc., avec les classes que vous avez utilisées pour afficher le menu contextuel ou sur son clic de menu contextuel ne devrait pas avoir d'effet. Vous devez donc définitivement ajouter la classe que vous utilisez pour ouvrir le menu contextuel.

Changer la classe .popup avec la classe popup.

0
Den Pat