Gunakan jQuery untuk menyembunyikan DIV ketika pengguna mengklik di luarnya


968

Saya menggunakan kode ini:

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

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

Dan HTML ini :

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

Masalahnya adalah saya memiliki tautan di dalamnya divdan kapan tautan itu tidak berfungsi lagi saat diklik.


6
Menggunakan javascript biasa, Anda dapat mencoba sesuatu seperti ini: jsfiddle.net/aamir/y7mEY
Aamir Afridi

menggunakan $('html')atau $(document)akan lebih baik daripada$('body')
Adrien Be

Jawaban:


2484

Punya masalah yang sama, muncul dengan solusi mudah ini. Itu bahkan bekerja rekursif:

$(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
Masukkan saja ke dalam proyek saya, tetapi dengan sedikit penyesuaian, menggunakan array elemen untuk mengulanginya sekaligus. jsfiddle.net/LCB5W
Thomas

5
@mpelzsherman Banyak orang berkomentar bahwa snipet bekerja pada perangkat sentuh tetapi karena postingan telah diedit, komentar ini agak hilang. TBH Saya tidak tahu apakah saya menggunakan "mouseup" untuk alasan tertentu tetapi jika itu juga bekerja dengan "klik" Saya tidak melihat alasan mengapa Anda tidak boleh menggunakan "klik".

6
Saya perlu wadah bersembunyi satu kali dengan acara ini, panggilan balik ini harus dihancurkan saat digunakan. Untuk melakukan itu, saya menggunakan namespace pada acara klik dengan bind ("click.namespace") dan ketika acara tersebut terjadi, saya sebut unbind ("click.namespace"). Dan akhirnya, saya menggunakan $ (e.target) .closest (". Container"). Panjang untuk mengenali wadah ... Jadi, saya tidak menggunakan trik apa pun dari jawaban ini: D
Loenix

80
Ingat untuk menggunakan $("YOUR CONTAINER SELECTOR").unbind( 'click', clickDocument );tepat di samping.hide() . Jadi documentjangan terus mendengarkan klik.
brasofilo

12
Untuk praktik terbaik yang saya tulis $(document).on("mouseup.hideDocClick", function () { ... });di fungsi yang membuka wadah, dan $(document).off('.hideDocClick');pada fungsi sembunyikan. Menggunakan ruang nama Saya tidak menghapus mouseuppendengar lain yang mungkin dilampirkan pada dokumen.
campsjos

204

Anda sebaiknya pergi dengan sesuatu seperti ini:

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

Pintar sekali! Apakah teknik ini standar?
advait

@ advait Saya tidak melihatnya digunakan sebelumnya. Ini semua tentang hoverpengendali acara, yang membuka banyak kemungkinan.
Makram Saleh

5
Saya tidak menganggap ini sebagai solusi yang baik karena ini membuat orang berpikir tidak apa-apa untuk mengisi objek window (= menggunakan variabel global).

1
Hanya untuk menambahkan sesuatu ke apa yang dikatakan @ prc322, Anda dapat membungkus kode Anda dengan fungsi anonim dan segera memanggilnya. (function() { // ... code })(); Saya tidak ingat nama dari pola ini, tetapi sangat berguna! Semua variabel Anda yang dideklarasikan akan berada di dalam fungsi dan tidak akan mencemari namespace global.
pedromanoel

3
@ prc322 Jika Anda bahkan tidak tahu cara mengubah ruang lingkup variabel, maka Anda benar, solusi ini tidak baik untuk Anda ... dan begitu pula JavaScript. Jika Anda hanya menyalin dan menempelkan kode dari Stack Overflow, Anda akan memiliki lebih banyak masalah daripada mungkin menimpa sesuatu di objek jendela.
Gavin

87

Kode ini mendeteksi setiap peristiwa klik pada halaman dan kemudian menyembunyikan #CONTAINERelemen tersebut jika dan hanya jika elemen yang diklik bukanlah #CONTAINERelemen maupun salah satu dari turunannya.

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

Ini sempurna!!
Mohd Abdul Mujib

@ 9KSoft Saya senang ini bisa membantu Anda. Terima kasih atas tanggapan Anda dan semoga sukses.
Kasus

Solusi ini bekerja dengan sempurna bagi saya menggunakan div sebagai wadah!
JCO9

76

Anda mungkin ingin memeriksa target acara klik yang menyala untuk tubuh alih-alih mengandalkan stopPropagation.

Sesuatu seperti:

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

Juga, elemen tubuh mungkin tidak termasuk seluruh ruang visual yang ditampilkan di browser. Jika Anda melihat bahwa klik Anda tidak mendaftar, Anda mungkin perlu menambahkan penangan klik untuk elemen HTML.


Yap, sekarang tautannya berfungsi! Tetapi untuk beberapa alasan, ketika saya mengklik tautannya, ia menembakkannya dua kali.
Scott Yu - membangun barang

Saya akhirnya menggunakan variasi ini. Saya pertama kali memeriksa apakah elemen terlihat kemudian jika target.hasClass saya sembunyikan.
Hawkee

dan jangan lupa e.stopPropagation();jika Anda memiliki pendengar klik lain
Darin Kolev

2
-1. Ini menyembunyikan form_wrapperketika Anda mengklik salah satu dari anak-anaknya, yang bukan perilaku yang diinginkan. Gunakan jawaban prc322 sebagai gantinya.
Mark Amery

38

DEMO langsung

Periksa area klik tidak ada dalam elemen yang ditargetkan atau di dalamnya anak

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

MEMPERBARUI:

jQuery stop propagation adalah solusi terbaik

DEMO langsung

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

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

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

Terima kasih atas pembaruannya, sempurna! Apakah ini berfungsi pada perangkat sentuh?
FFish

1
Dalam hal ini, Anda memiliki beberapa dropdown pada satu halaman. Saya pikir Anda harus menutup semua dropdown sebelum membuka clickedsatu. Jika tidak, itu stopPropagationakan memungkinkan beberapa dropdown terbuka pada saat yang sama.
T04435

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

2
Hmmm ... Jika saya mengklik sesuatu DI DALAM div, seluruh div menghilang karena alasan tertentu.
Scott Yu - membangun barang

11
Alih-alih memeriksa apakah target memiliki kelas, coba: if ($ (event.target) .closest ('. Form_wrapper) .get (0) == null) {$ (". Form_wrapper"). Hide (); } Ini akan memastikan bahwa mengklik hal-hal di dalam div tidak akan menyembunyikan div.
John Haager

17

Memperbarui solusi untuk:

  • gunakan mouseenter dan mouseleave sebagai gantinya
  • dari hover gunakan 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');
    }
});

1
.livesekarang sudah ditinggalkan ; gunakan .onsaja.
Brett


9

Demo langsung dengan ESCfungsionalitas

Bekerja di Desktop dan Mobile

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

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

Jika untuk beberapa kasus Anda perlu memastikan bahwa elemen Anda benar-benar terlihat ketika Anda mengklik pada dokumen: if($pop.is(':visible') && (notH||e.which==27)) $pop.hide();


8

Bukankah hal seperti ini akan berhasil?

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

});

atau

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

});

4
Jawaban ini tidak benar. Seperti banyak jawaban di sini, ini akan menyembunyikan .form_wrapperketika Anda mengklik anak-anaknya (di antara masalah lain).
Mark Amery

6

Bahkan sleaker:

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

4
Jawaban ini tidak benar. Ini akan menyembunyikan di .wrappermana pun Anda mengklik pada halaman, yang bukan apa yang diminta.
Mark Amery

6

Alih-alih mendengarkan setiap klik pada DOM untuk menyembunyikan satu elemen tertentu, Anda dapat mengatur tabindexke orang tua <div>dan mendengarkan focusoutacara.

Pengaturan tabindexakan memastikan bahwa bluracara diaktifkan pada <div>(biasanya tidak).

Jadi HTML Anda akan terlihat seperti:

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

Dan JS Anda:

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

5

Dan untuk perangkat Touch seperti iPad dan IPHONE kita dapat menggunakan kode berikut

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

Inilah jsfiddle yang saya temukan di utas lain, bekerja dengan kunci esc juga: 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()
      }
    })

Saya melihatnya mendeteksi apakah acara 'klik' ada di dalam elemen #test .. mencoba tautan tes sebagai jsfiddle.net/TA96A & sepertinya bisa berfungsi.
Thomas W

Ya, sepertinya jsfiddle memblokir tautan di luar. Jika Anda menggunakan http: // jsfiddle.net Anda akan melihat halaman hasil memproses tautannya :)
djv

5

Dibangun dari jawaban mengagumkan 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);
    }
  });
}

Ini menambahkan beberapa hal ...

  1. Ditempatkan dalam fungsi dengan panggilan balik dengan argumen "tidak terbatas"
  2. Menambahkan panggilan ke .off () jquery yang dipasangkan dengan namespace acara untuk melepaskan ikatan acara dari dokumen setelah dijalankan.
  3. Termasuk touchend untuk fungsionalitas seluler

Saya harap ini membantu seseorang!



4

(Hanya menambahkan jawaban prc322.)

Dalam kasus saya, saya menggunakan kode ini untuk menyembunyikan menu navigasi yang muncul ketika pengguna mengklik tab yang sesuai. Saya menemukan bermanfaat untuk menambahkan kondisi tambahan, bahwa target klik di luar wadah bukanlah tautan.

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

Ini karena beberapa tautan di situs saya menambahkan konten baru ke halaman. Jika konten baru ini ditambahkan pada saat yang sama ketika menu navigasi menghilang, itu mungkin membingungkan bagi pengguna.


4

Begitu banyak jawaban, harus menjadi hak lintas untuk menambahkan satu ... Saya tidak melihat jawaban saat ini (jQuery 3.1.1) - jadi:

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

padalah nama elemen. Di mana orang dapat melewati id atau nama kelas atau elemen juga.


3

Kembali salah jika Anda mengklik .form_wrapper:

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

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

3

Lampirkan acara klik ke elemen tingkat atas di luar pembungkus formulir, misalnya:

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

Ini juga akan berfungsi pada perangkat sentuh, pastikan Anda tidak menyertakan induk dari .form_wrapper dalam daftar pemilih Anda.


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

}); 

BIOLA


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

Disalin dari https://sdtuts.com/click-on-not-specified-element/

Demo langsung 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

saya melakukannya seperti ini:

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

Dengan menggunakan kode ini Anda dapat menyembunyikan item sebanyak yang Anda inginkan

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

Yang dapat Anda lakukan adalah mengikat acara klik ke dokumen yang akan menyembunyikan dropdown jika sesuatu di luar dropdown diklik, tetapi tidak akan menyembunyikannya jika sesuatu di dalam dropdown diklik, sehingga acara "show" Anda (atau slidesown atau apa pun menunjukkan 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();
            }
        });

    });

Lalu ketika menyembunyikannya, batalkan ikatan acara klik

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

0

Menurut dokumen , .blur()berfungsi lebih dari sekadar <input>tag. Sebagai contoh:

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

-1, tidak bekerja. Ide yang sangat menarik, tetapi dokumen jQuery salah. Lihat developer.mozilla.org/en-US/docs/Web/API/… , misalnya: "Berbeda dengan MSIE - di mana hampir semua jenis elemen menerima peristiwa blur - hampir semua jenis elemen pada peramban Gecko JANGAN bekerja dengan acara ini. " Juga, diuji di Chrome, dan divtidak pernah blur - blur even bahkan tidak bisa keluar dari anak-anak mereka. Akhirnya, bahkan jika di atas tidak benar, ini hanya akan berfungsi jika Anda memastikan bahwa .form_wrapperitu dalam fokus sebelum pengguna mematikannya.
Mark Amery
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.