Kullanıcı dışına tıkladığında DIV'yi gizlemek için jQuery kullanma


967

Bu kodu kullanıyorum:

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

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

Ve bu HTML :

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

Sorun ben içinde divtıkladığında ve artık çalışmıyor bağlantıları içinde olmasıdır .


6
Düz javascript kullanarak böyle bir şey deneyebilirsiniz: jsfiddle.net/aamir/y7mEY
Aamir Afridi

kullanarak $('html')ya $(document)da daha iyi olurdu$('body')
Adrien Be

Yanıtlar:


2484

Aynı sorun vardı, bu kolay çözüm ortaya çıktı. Hatta özyinelemeli çalışıyor:

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

19
Sadece benim projeme koymak, ama küçük bir ayarlama ile, hepsini bir kerede döngü döngü öğeleri kullanarak. jsfiddle.net/LCB5W
Thomas

5
@mpelzsherman Birçok kişi snippet'in dokunmatik cihazlarda çalıştığını yorumladı, ancak yazı düzenlendiği için bu yorumlar biraz kayboldu. TBH Belirli bir nedenden dolayı "mouse" kullanıp kullanmadığımı bilmiyorum ama eğer "click" ile de çalışırsa "click" kullanmamanız için hiçbir neden göremiyorum.

6
Ben bu olay ile konteyner bir kez gizlemek gerekiyordu, bu geri arama kullanıldığında imha edilmelidir. Bunu yapmak için, bind ("click.namespace") ile click olayında ad alanı kullandım ve olay gerçekleştiğinde unbind ("click.namespace") diyorum. Ve son olarak, ben $ kullanılan (e.target) .closest ( "kapsayıcı".) Konteyner ... Yani, bu cevap herhangi hile kullanmak vermedi tanımak uzunluğu: D.
Loenix

80
$("YOUR CONTAINER SELECTOR").unbind( 'click', clickDocument );Hemen yanında kullanmayı hatırlamak.hide() . Bu yüzden documenttıklamaları dinlemeye devam etmeyin.
brasofilo

12
En iyi uygulamalar $(document).on("mouseup.hideDocClick", function () { ... });için kapsayıcıyı açan fonksiyonda ve $(document).off('.hideDocClick');hide fonksiyonunda yazmıştım . Ad alanlarını kullanarak mouseupbelgeye bağlı diğer olası dinleyicileri kaldırmıyorum .
campsjos

204

Böyle bir şey yapsan iyi olur:

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

Ne kadar zekice! Bu teknik standart mı?
advait

@advait Daha önce kullanıldığını görmedim. Her şey, hoverbirçok olasılık açan olay işleyicisiyle ilgilidir.
Makram Saleh

5
Ben insanların pencere nesnesi (= genel değişkenleri kullanarak) doldurmak için iyi olduğunu düşünüyorum sağlar çünkü bu iyi bir çözüm olarak düşünmüyorum.

1
@ Prc322'nin söylediklerine bir şeyler eklemek için, kodunuzu anonim bir işlevle sarabilir ve hemen çağırmasını sağlayabilirsiniz. (function() { // ... code })(); Bu desen adını hatırlamıyorum, ama süper kullanışlı! Bildirilen tüm değişkenleriniz işlevin içinde bulunur ve genel ad alanını kirletmez.
pedromanoel

3
@ prc322 Bir değişkenin kapsamını nasıl değiştireceğinizi bile bilmiyorsanız, haklısınız, bu çözüm sizin için iyi değildir ... ve ikisi de JavaScript değildir. Stack Overflow'dan sadece kodu kopyalayıp yapıştırıyorsanız, pencere nesnesindeki bir şeyin üzerine yazmaktan çok daha fazla sorun yaşarsınız.
Gavin

87

Bu kod, sayfadaki herhangi bir tıklama olayını algılar #CONTAINERve yalnızca tıklatılan #CONTAINERöğenin ne öğesi ne de onun alt öğelerinden biri olması durumunda öğeyi gizler .

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

Bu harika!!
Mohd Abdul Mujib

@ 9KSoft Size yardımcı olabildiğine sevindim. Geri bildiriminiz ve bol şans için teşekkür ederiz.
Dava

Bu çözüm bir div olarak konteyner kullanarak benim için mükemmel çalıştı!
JCO9

76

StopPropagation öğesine güvenmek yerine gövde için tetiklenen tıklama etkinliğinin hedefini kontrol etmek isteyebilirsiniz.

Gibi bir şey:

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

Ayrıca, gövde öğesi tarayıcıda gösterilen tüm görsel alanı içermeyebilir. Tıklamalarınızın kaydedilmediğini fark ederseniz, bunun yerine HTML öğesi için tıklama işleyicisini eklemeniz gerekebilir.


Evet, şimdi bağlantılar çalışıyor! Ancak bir nedenden dolayı, bağlantıyı tıkladığımda, iki kez tetikler.
Scott Yu -

Sonunda bunun bir varyasyonunu kullandım. Önce öğenin görünüp görünmediğini kontrol ederim ve sonra target.hasClass'ı gizlerim.
Hawkee

ve e.stopPropagation();başka bir tıklama dinleyiciniz varsa unutmayın
Darin Kolev

2
-1. Bu form_wrapper, çocuklarından birini tıklattığınızda gizlenir , bu da istenen davranış değildir. Bunun yerine prc322'nin cevabını kullanın.
Mark Amery

38

Canlı DEMO

Tıklama alanının hedeflenen öğede veya alt öğede olmadığını kontrol edin

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

GÜNCELLEME:

jQuery stop yayılımı en iyi çözümdür

Canlı DEMO

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

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

$(document).click(function(){
    $(".dropdown").hide();
});

Güncelleme için teşekkürler, mükemmel! Dokunmatik cihazlarda çalışıyor mu?
FFish

1
Bu durumda, bir sayfada birden fazla açılır listeniz olur. clickedBirini açmadan önce tüm açılır menüleri kapatmanız gerekeceğini düşünüyorum . Aksi takdirde, stopPropagationaynı anda birden fazla açılır listenin açık olması mümkün olur.
T04435

19
$(document).click(function(event) {
    if ( !$(event.target).hasClass('form_wrapper')) {
         $(".form_wrapper").hide();
    }
});

2
Hmmm ... Div'in içindeki bir şeye tıklarsam, tüm div bir nedenden dolayı kaybolur.
Scott Yu -

11
Hedefin sınıfa sahip olup olmadığını kontrol etmek yerine şunu deneyin: if ($ (event.target) .closest ('. Form_wrapper) .get (0) == null) {$ (". Form_wrapper"). Hide (); } Bu, div içindeki öğelere tıklamanın div öğesini gizlememesini sağlar.
John Haager

17

Çözüm güncellendi:

  • bunun yerine mouseenter ve mouseleave kullanın
  • fareyle üzerine gelindiğinde canlı olay bağlama kullanma

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

1
.liveartık kullanımdan kaldırıldı ; kullanın .on.
Brett


9

ESCİşlevselliğe sahip canlı demo

Hem Masaüstü hem de Mobil Cihazlarda Çalışır

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

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

Bazı durumlarda, dokümanı tıkladığınızda öğenizin gerçekten görünür olduğundan emin olmanız gerekiyorsa: if($pop.is(':visible') && (notH||e.which==27)) $pop.hide();


8

Böyle bir şey olmaz mı?

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

});

veya

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

});

4
Bu cevap doğru değil. Buradaki birçok cevap gibi, bu .form_wrapperda çocuklarını tıkladığınızda gizlenir (diğer sorunların yanı sıra).
Mark Amery

6

Hatta daha ince:

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

4
Bu cevap doğru değil. Bu .wrapper, sayfayı nereden tıklarsanız kullansanız da gizlenecektir .
Mark Amery

6

Belirli bir öğeyi gizlemek için DOM üzerindeki her bir tıklamayı dinlemek yerine tabindex, üst öğeye ayarlayabilir <div>ve focusoutetkinlikleri dinleyebilirsiniz .

Ayarlama tabindex, bluretkinliğin tetiklendiğinden emin <div>olur (normalde gerçekleşmez).

Böylece HTML'niz şöyle görünecektir:

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

Ve JS'niz:

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

5

IPAD ve IPHONE gibi Dokunmatik cihazlar için aşağıdaki kodu kullanabiliriz

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

5

İşte başka bir iş parçacığında bulduğum bir jsfiddle, esc anahtarı ile de çalışıyor: 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()
      }
    })

Ben bağlantıları tesing .. o 'tık' olay #test öğesi içinde olup olmadığını tespit eder çalıştı bkz jsfiddle.net/TA96A onlar işe yarayabilecek gibi & görünüyor.
Thomas W

Evet, bağlantılar dışında jsfiddle blokları gibi görünüyor. Http: // jsfiddle.net kullanıyorsanız sonuç sayfasının bağlantıyı işlediğini göreceksiniz :)
djv

5

Prc322'nin müthiş cevabından oluşturuldu.

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

Bu birkaç şey ekliyor ...

  1. "Sınırsız" bağımsız değişkenlere sahip bir geri çağrı bulunan bir işlev içine yerleştirilir
  2. Jquery'nin .off () öğesine, olay çalıştırıldıktan sonra olayı belgeden ayırmak için bir olay ad alanı ile eşleştirilmiş bir çağrı eklendi.
  3. Mobil işlevler için dahil dokunmatik ekran

Umarım bu birine yardımcı olur!



4

(Sadece prc322'nin cevabına ekliyoruz.)

Benim durumumda, kullanıcı uygun bir sekmeyi tıklattığında görünen bir gezinme menüsünü gizlemek için bu kodu kullanıyorum. Kapsayıcı dışındaki tıklamanın hedefinin bir bağlantı olmadığı ekstra bir koşul eklemenin yararlı olduğunu buldum .

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

Bunun nedeni, sitemdeki bazı bağlantıların sayfaya yeni içerik eklemesidir. Bu yeni içerik, navigasyon menüsünün kaybolmasıyla aynı zamanda eklenirse, kullanıcı için yönünü kötüleştirebilir.


4

Pek çok cevap, bir tane eklemek için bir geçiş hakkı olmalı ... Geçerli (jQuery 3.1.1) cevapları görmedim - yani:

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

3
var n = 0;
$("#container").mouseenter(function() {
n = 0;

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

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

3
 $('body').click(function(event) {
    if (!$(event.target).is('p'))
    {
        $("#e2ma-menu").hide();
    }
});

pöğe adıdır. Burada kimlik veya sınıf veya öğe adı da geçebilir.


3

.Form_wrapper öğesini tıklatırsanız false değerini döndürün:

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

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

3

Form sarmalayıcı dışındaki en üst düzey öğelere bir tıklama etkinliği ekleyin, örneğin:

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

Bu aynı zamanda dokunmatik cihazlarda da çalışır, seçiciler listenize .form_wrapper öğesinin üst öğesini eklemediğinizden emin olun.


3

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

}); 

VAKTİNİ BOŞA HARCAMAK


3

$(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>


3

Https://sdtuts.com/click-on-not-specified-element/ adresinden kopyalandı

Canlı 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");
        }
    })
})

2

ben böyle yaptım:

var close = true;

$(function () {

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

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


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

});

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

2

Bu kodu kullanarak istediğiniz kadar öğe gizleyebilirsiniz

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

Yapabileceğiniz şey, açılır menü dışındaki bir şey tıklandığında açılır listeyi gizleyen belgeye bir tıklama etkinliği bağlamaktır, ancak açılır menüdeki bir şey tıklandığında gizlenmez, bu nedenle "göster" etkinliğiniz (veya slayt gösterisi veya açılır listeyi gösterir)

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

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

    });

Ardından gizlerken tıklama etkinliğini çözün

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

0

Docs göre , .blur()daha uzun süre çalışır <input>etiketi. Örneğin:

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

-1, çalışmıyor. Çok ilginç bir fikir, ancak jQuery belgeleri yanlış. Örneğin developer.mozilla.org/tr-TR/docs/Web/API/… adresine bakın : "MSIE'nin aksine - neredeyse her türlü öğenin bulanıklık etkinliğini aldığı - Gecko tarayıcılarındaki hemen hemen her türlü öğe bu etkinlikle ÇALIŞMAYIN. " Ayrıca, Chrome'da test edildi ve divhiçbir zaman bulanık değil - bulanıklaştırma olayları çocuklarından bile kabarcık olamaz. Son olarak, yukarıdakiler doğru olmasa bile, bu yalnızca .form_wrapperkullanıcının tıklamadan önce odakta olduğundan emin olsaydınız işe yarardı.
Mark Amery
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.