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.

Scott Yu - membuat barang
sumber
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();
    }
});

sumber
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();
    });
});
Makram Saleh
sumber
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();
    }
});
Kasus
sumber
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.

David Andres
sumber
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();
});
MaxEcho
sumber
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();
    }
});
meder omuraliev
sumber
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');
    }
});
benvds
sumber
1
.livesekarang sudah ditinggalkan ; gunakan .onsaja.
Brett
15

Solusi tanpa jQuery untuk jawaban paling populer :

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

Martin Vseticka
sumber
bindtidak ada yang berhasil. Bisakah Anda memperbaiki fungsi untuk membuatnya berfungsi?
Memmo
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();

Roko C. Buljan
sumber
8

Bukankah hal seperti ini akan berhasil?

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

});

atau

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

});
MRVDOG
sumber
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();
});
Olivenbaum
sumber
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();
});
Oscar
sumber
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();
    }
});
Kode Mata-mata
sumber
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()
      }
    })
djv
sumber
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!

WiseOlMan
sumber
4

jika Anda memiliki masalah dengan ios, mouseup tidak berfungsi pada perangkat apple.

apakah mousedown / mouseup di jquery berfungsi untuk ipad?

saya menggunakan ini:

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

          if (container.has(e.target).length === 0)
          {
              container.hide();
          }
      });
pengguna2271066
sumber
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.

shngrdnr
sumber
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();
    });
});
zak
sumber
3
var n = 0;
$("#container").mouseenter(function() {
n = 0;

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

$("html").click(function(){ 
if (n == 1) {
alert("clickoutside");
}
});
Gary
sumber
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.

Abhishek
sumber
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();
//});
bogo
sumber
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.

ThornberryPie
sumber
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

Sharma Patat
sumber
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>

RustBeard
sumber
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");
        }
    })
})
pengguna3151197
sumber
2

saya melakukannya seperti ini:

var close = true;

$(function () {

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

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


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

});
pengguna2822517
sumber
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);
    }
});
Abed Yaseen
sumber
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';
    }
   }
})
Mahdi Younesi
sumber
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');
jeffsaracco
sumber
0

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

$('.form_wrapper').blur(function(){
   $(this).hide();
});
Bizley
sumber
-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