Hindari menu dropdown tutup klik di dalam

310

Saya memiliki menu tarik-turun Bootstrap Twitter. Seperti yang diketahui semua pengguna Twitter Bootstrap, menu dropdown ditutup saat klik (bahkan mengklik di dalamnya).

Untuk menghindari ini, saya dapat dengan mudah melampirkan pengendali event klik pada menu dropdown dan cukup menambahkan yang terkenal event.stopPropagation().

<ul class="nav navbar-nav">
  <li class="dropdown mega-dropdown">
    <a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown">
      <i class="fa fa-list-alt"></i> Menu item 1
      <span class="fa fa-chevron-down pull-right"></span>
    </a>
    <ul class="dropdown-menu mega-dropdown-menu">
      <li>
        <div id="carousel" class="carousel slide" data-ride="carousel">
          <ol class="carousel-indicators">
            <li data-slide-to="0" data-target="#carousel"></li>
            <li class="active" data-slide-to="1" data-target="#carousel"></li>
          </ol>
          <div class="carousel-inner">
            <div class="item">
              <img alt="" class="img-rounded" src="img1.jpg">
            </div>
            <div class="item active">
              <img alt="" class="img-rounded" src="img2.jpg">
            </div>
          </div>
          <a data-slide="prev" role="button" href="#carousel" 
             class="left carousel-control">
            <span class="glyphicon glyphicon-chevron-left"></span>
          </a>
          <a data-slide="next" role="button" href="#carousel" 
             class="right carousel-control">
            <span class="glyphicon glyphicon-chevron-right"></span>
          </a>
        </div>
      </li>
    </ul>
  </li>
</ul>

Ini terlihat mudah dan merupakan perilaku yang sangat umum, dan karena carousel-controls(dan juga carousel indicators) penangan event didelegasikan ke documentobjek, clickperistiwa pada elemen-elemen ini ( kontrol selanjutnya , ...) akan "diabaikan".

$('ul.dropdown-menu.mega-dropdown-menu').on('click', function(event){
    // The event won't be propagated up to the document NODE and 
    // therefore delegated events won't be fired
    event.stopPropagation();
});

Mengandalkan dropdown hide/ hiddenacara Bootstrap Twitter bukanlah solusi karena alasan berikut:

  • Objek acara yang disediakan untuk kedua penangan acara tidak memberikan referensi ke elemen yang diklik
  • Saya tidak memiliki kontrol atas konten menu dropdown sehingga menambahkan flagkelas atau atribut tidak mungkin

Biola ini adalah perilaku normal dan biola ini event.stopPropagation()ditambahkan.

Memperbarui

Terima kasih kepada Roman atas jawabannya . Saya juga menemukan jawaban yang dapat Anda temukan di bawah .

php-dev
sumber
1. Jsfiddle Anda tidak berfungsi. 2. Apa sebenarnya yang ingin Anda capai?
paulalexandru
1
@paulalexandru, Diperbarui, menambahkan dua biola. Satu perilaku standar, dan satu dengan modifikasi. Coba klik tombol berikutnya & sebelumnya, atau pada indikator. Sebagai contoh pertama, menu menyembunyikan & slide korsel. atau contoh kedua: Menu tetap terbuka, tetapi korsel tidak meluncur karena event propagationtelah dihentikan.
php-dev
@paulalexandru Mengerti, Benar?
php-dev
@ php-dev: saya telah memperbaruinya lagi demi tantangan, sekarang sempurna ... lihat demo.
Luca Filosofi

Jawaban:

373

Menghapus atribut data data-toggle="dropdown"dan menerapkan buka / tutup dropdown dapat menjadi solusi.

Pertama dengan menangani klik pada tautan untuk membuka / menutup dropdown seperti ini:

$('li.dropdown.mega-dropdown a').on('click', function (event) {
    $(this).parent().toggleClass('open');
});

dan kemudian mendengarkan klik di luar dropdown untuk menutupnya seperti ini:

$('body').on('click', function (e) {
    if (!$('li.dropdown.mega-dropdown').is(e.target) 
        && $('li.dropdown.mega-dropdown').has(e.target).length === 0 
        && $('.open').has(e.target).length === 0
    ) {
        $('li.dropdown.mega-dropdown').removeClass('open');
    }
});

Ini adalah demo: http://jsfiddle.net/RomaLefrancois/hh81rhcm/2/

Roma
sumber
2
Solusi ini berfungsi dengan baik. Hadiah harus diberikan kepada Anda jika tidak ada jawaban lain.
php-dev
1
Solusi Anda berfungsi, generik, dan juga "populer". Karunia harus diberikan kepada jawaban Anda. Saya juga menemukan jawaban, lihat di bawah ini;)
php-dev
1
@Cichy ... cukup modifikasi penangan pertama seperti ini ... $ ('li.dropdown.mega-dropdown a'). On ('klik', fungsi (event) {$ ('li.dropdown.mega-dropdown .open '). removeClass (' open '); $ (this) .parent (). toggleClass (' open ');});
dsaket
63
Jawaban yang disukai ini adalah peretasan. Wow!!! Berikut ini adalah jawaban ALPHA BOOTSTRAP 4 yang lebih sederhana untuk mencegah klik di dalam mega-dropdown. // PREVENT INSIDE CLICK DROPDOWN $('.dropdown-menu').on("click.bs.dropdown", function (e) { e.stopPropagation(); e.preventDefault(); });
Frank Thoeny
7
e.stopPropagation()adalah solusi terbaik.
nacholibre
332

Ini akan membantu juga

$(document).on('click', 'someyourContainer .dropdown-menu', function (e) {
  e.stopPropagation();
});
Arbejdsglæde
sumber
33
Saya pikir itu pasti solusi paling sederhana untuk masalah ini. Acungan jempol - baru menguji yang ini dan berhasil!
Torsten Barthel
13
Sejauh ini, ini adalah solusi terbaik.
sunyi
3
Itu solusi yang paling umum, tetapi saya memiliki persyaratan yang berbeda. Harap baca dengan cermat pertanyaan saya :)
php-dev
4
Solusi terbaik untuk menjaga menu tetap terbuka pada klik.
Matt Pierce
2
Solusi terbaik memang. Saya pribadi menggunakan '.dropdown-menu :not(.dropdown-item)'sehingga mengklik pada dropdown-itemtidak menutup popup, tetapi mengklik pada dropdown-headertidak.
Benjamin
41

Bootstrap menyediakan fungsi berikut:

                 | Acara ini dipecat segera ketika metode contoh menyembunyikan
hide.bs.dropdown | sudah dipanggil. Elemen jangkar toggling tersedia sebagai
                 | properti terkait Target dari acara tersebut.

Oleh karena itu, menerapkan fungsi ini harus dapat menonaktifkan dropdown dari penutupan.

$('#myDropdown').on('hide.bs.dropdown', function (e) {
    var target = $(e.target);
    if(target.hasClass("keepopen") || target.parents(".keepopen").length){
        return false; // returning false should stop the dropdown from hiding.
    }else{
        return true;
    }
});
Vartan
sumber
2
@Vartan, Juga targetproperti acara adalah li.dropdown, relatedTargetini adalah a.dropdown-toggle. Jadi Anda tidak bisa merujuk ke elemen yang diklik di dalam hidepengendali event.
php-dev
2
hasClass mengambil nama kelas, bukan pemilih CSS. target.hasClass(".keepopen")seharusnya target.hasClass("keepopen"). Kalau tidak, kodenya tidak akan berfungsi.
Hugh Guiney
3
Saya telah memindai internet dan sejauh ini, ini adalah solusi paling cerdas, karena alasan ini ... msot metode lain memerlukan pendekatan yang menggunakan penghentian acara default atau menghentikan propagasi. pendekatan ini sangat buruk karena mereka akan memecah peristiwa yang dipicu lainnya di dalam drop-down (yaitu elemen bentuk mobile jquery saya) menggunakan pendekatan ini memungkinkan Anda untuk secara khusus mengidentifikasi ketika menu itu sendiri ditutup dan memungkinkan Anda untuk mengambil tindakan pada peristiwa itu saja. jawaban ini membutuhkan banyak bintang ....
webfish
3
@ ikan web Berapa banyak yang Anda butuhkan untuk memindai internet? (rofl)
php-dev
2
Mungkin ini dulu berfungsi .. tetapi dengan bootstrap 4, e.target selalu merupakan dropdown itu sendiri. Bukan target yang diklik. Bahkan jika Anda mengklik di luar dropdown, e.target masih dropdown. Jadi, Anda tidak dapat melakukan pemeriksaan semacam ini. Adakah yang melihat jalan keluarnya?
FredArters
36

Jawaban terbaik mutlak adalah menempatkan tag formulir setelah menu dropdown kelas

jadi kodemu

<ul class="dropdown-menu">
  <form>
    <li>
      <div class="menu-item">bla bla bla</div>
    </li>
  </form>
</ul>
Gregory Bowers
sumber
2
secara fungsional bekerja dengan baik untuk saya, tetapi merusak styling
2778
2
ini adalah solusi tercepat bagi saya
Jonathan Morales Vélez
15
Ini bukan jawaban terbaik :) sebuah <li>elemen tidak boleh berada di dalam sebuah <form> elemen.
GETah
2
Ini bukan solusi semanticlyly benar - satu-satunya anak yang valid dari UL adalah LI - jika apa pun tag bentuk harus di dalam tag li - tapi itu mungkin tidak allwo tindakan yang diinginkan - baik cara ul> form> li tidak markup yang benar
gavgrif
2
Terima kasih atas solusi cepat ini
Herman Demsong
27

Saya juga menemukan solusinya.

Dengan asumsi bahwa Twitter Bootstrap Componentspenangan peristiwa terkait didelegasikan ke documentobjek, saya melingkar penangan terlampir dan memeriksa apakah elemen yang diklik saat ini (atau salah satu dari orang tuanya) prihatin dengan peristiwa yang didelegasikan.

$('ul.dropdown-menu.mega-dropdown-menu').on('click', function(event){
    var events = $._data(document, 'events') || {};
    events = events.click || [];
    for(var i = 0; i < events.length; i++) {
        if(events[i].selector) {

            //Check if the clicked element matches the event selector
            if($(event.target).is(events[i].selector)) {
                events[i].handler.call(event.target, event);
            }

            // Check if any of the clicked element parents matches the 
            // delegated event selector (Emulating propagation)
            $(event.target).parents(events[i].selector).each(function(){
                events[i].handler.call(this, event);
            });
        }
    }
    event.stopPropagation(); //Always stop propagation
});

Semoga ini membantu siapa pun yang mencari solusi serupa.

Terima kasih atas bantuannya.

php-dev
sumber
1
Wow!!! bekerja dengan sempurna! Bermasalah selama seminggu, saya menggunakan mCustomeScrollbar dan setelah mengklik pada scrollbar di drop down itu menutupnya, skrip Anda bekerja dan sekarang berfungsi dengan baik! Terima kasih banyak.
eirenaios
bekerja hebat! bagaimana cara memperpanjang ini, sehingga pengguna masih dapat menekan "ESC" (atau bahkan mengklik di luar) pada keyboard untuk menutup DD?
Paman Iroh
2
@ MaggewDotCom Tekan tombol ESC masih harus berfungsi. Hal yang sama untuk mengklik di luar ...
php-dev
Satu-satunya downside dari solusi ini adalah tidak memungkinkan dropdown bersarang (katakanlah Anda memiliki dropright di dalam dropdown). Apakah ada solusi untuk kasus ini?
sdvnksv
26

Ini mungkin membantu:

$("dropdownmenuname").click(function(e){
   e.stopPropagation();
})
Bawantha
sumber
Ini jelas merupakan jawaban paling sederhana / terbaik jika Anda ingin pengguna berinteraksi dengan elemen UI yang ada pada dropdown (mis. Tombol radio) dan tidak ingin menu ditutup ketika mereka beralih opsi.
Rob
22
$('body').on("click", ".dropdown-menu", function (e) {
    $(this).parent().is(".open") && e.stopPropagation();
});

Ini dapat bekerja untuk kondisi apa pun.

Terry Lin
sumber
ini seharusnya jawaban yang benar karena menggunakan lebih sedikit baris kode daripada jawaban yang dipilih
Muhammad Omer Aslam
@MuhammadOmerAslam Nah! Karena tidak memenuhi persyaratan saya
php-dev
12

jQuery:

<script>
  $(document).on('click.bs.dropdown.data-api', '.dropdown.keep-inside-clicks-open', function (e) {
    e.stopPropagation();
  });
</script>

HTML:

<div class="dropdown keep-inside-clicks-open">
  <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">
     Dropdown Example
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu">
    <li><a href="#">HTML</a></li>
    <li><a href="#">CSS</a></li>
    <li><a href="#">JavaScript</a></li>
  </ul>
</div>

Demo :

Umum: https://jsfiddle.net/kerryjohnson/omefq68b/1/

Demo Anda dengan solusi ini: http://jsfiddle.net/kerryjohnson/80oLdtbf/101/

Kerry Johnson
sumber
9

Saya mencoba hal sederhana ini dan berhasil seperti pesona.

Saya mengubah elemen menu dropdown dari <div>ke <form>dan itu bekerja dengan baik.

<div class="nav-item dropdown" >
  <a href="javascript:;" class="nav-link dropdown-toggle" data-toggle="dropdown">
   Click to open dropdown
 </a>
 <form class="dropdown-menu   ">
  <ul class="list-group text-black">
     <li class="list-group-item"  >
     </li>
     <li class="list-group-item"   >
     </li>
  </ul>
</form>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>

<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>


<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>


<div class="nav-item dropdown" >
  <a href="javascript:;" class="nav-link dropdown-toggle" data-toggle="dropdown">
   Click to open dropdown
 </a>
 <form class="dropdown-menu   ">
  <ul class="list-group text-black">
     <li class="list-group-item"  >
      List Item 1
     </li>
     <li class="list-group-item"   >
         LI 2<input class="form-control" />
     </li>
     <li class="list-group-item"   >
        List Item 3
     </li>
  </ul>
</form>

TheVigilant
sumber
6

Aku punya masalah yang sama baru-baru ini dan mencoba berbagai cara untuk mengatasinya dengan menghapus data atribut data-toggle="dropdown"dan mendengarkan clickdenganevent.stopPropagation() menelepon.

Cara kedua terlihat lebih disukai. Pengembang Bootstrap juga menggunakan cara ini. Di file sumber saya menemukan inisialisasi elemen dropdown:

// APPLY TO STANDARD DROPDOWN ELEMENTS
$(document)
.on('click.bs.dropdown.data-api', clearMenus)
.on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
.on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
.on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
.on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
}(jQuery);

Jadi, baris ini:

.on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })

menyarankan Anda dapat meletakkan formelemen di dalam wadah dengan kelas .dropdownuntuk menghindari penutupan menu dropdown.

Ilya
sumber
6

Bootstrap telah memecahkan masalah ini sendiri dengan dukungan mereka untuk <form>tag dalam dropdown. Solusi mereka cukup dapat dipahami dan Anda dapat membacanya di sini: https://github.com/twbs/bootstrap/blob/v4-dev/js/src/dropdown.js

Itu bermuara untuk mencegah propagasi pada elemen dokumen dan melakukannya hanya untuk acara bertipe 'click.bs.dropdown.data-api'yang cocok dengan pemilih'.dropdown .your-custom-class-for-keep-open-on-click-elements' .

Atau dalam kode

$(document).on('click.bs.dropdown.data-api', '.dropdown .keep-open-on-click', (event) => {
    event.stopPropagation();
});
Daniel Schlaug
sumber
1
Terima kasih terima kasih terima kasih atas tautan ke sumbernya. Bagi yang lain bertanya-tanya mengapa formpendekatan dari contoh tidak bekerja untuk Anda - saya menggunakan kelas dropleft, tetapi juga perlu dropdownagar pemilih formulir cocok.
Mark K Cowan
6

Saya memodifikasi jawaban @ Vartan agar berfungsi dengan Bootstrap 4.3. Solusinya tidak berfungsi lagi dengan versi terbaru karena targetproperti selalu mengembalikan root dropdowndiv mana pun klik ditempatkan.

Ini kodenya:

$('.dropdown-keep-open').on('hide.bs.dropdown', function (e) {
  if (!e.clickEvent) {
    // There is no `clickEvent` property in the `e` object when the `button` (or any other trigger) is clicked. 
    // What we usually want to happen in such situations is to hide the dropdown so we let it hide. 
    return true;
  }

  var target = $(e.clickEvent.target);

  return !(target.hasClass('dropdown-keep-open') || target.parents('.dropdown-keep-open').length);
});
<div class="dropdown dropdown-keep-open">
  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    Dropdown button
  </button>
  <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
    <a class="dropdown-item" href="#">Action</a>
    <a class="dropdown-item" href="#">Another action</a>
    <a class="dropdown-item" href="#">Something else here</a>
  </div>
</div>
Konrad Kalemba
sumber
oneline:$('.dropdown-keep-open').on('hide.bs.dropdown', ev => !(ev.clickEvent && $(ev.target).has(ev.clickEvent.target).length))
Matveev Dmitriy
@ MatveevDmitriy Saya minta maaf tapi tidak ada, tidak ada yang bisa membaca ini Menulis kode dengan cara ini adalah praktik yang buruk.
ViRuSTriNiTy
Baris terakhir dapat disederhanakan menggunakan return !target.closest('.dropdown-keep-open').length). Yang mengatakan, ini adalah solusi hebat! Menemukan ini diperlukan untuk menyelesaikan masalah ini.
patrick3853
6
$('body').on("click", ".dropdown-menu", function (e) {
    $(this).parent().is(".show") && e.stopPropagation();
});
waza123
sumber
Pertama, terima kasih atas jawaban Anda. Pertanyaannya sudah dijawab. Juga, saya memiliki persyaratan berbeda seperti yang dijelaskan dalam pertanyaan daripada persyaratan umum.
php-dev
4
$('ul.nav.navbar-nav').on('click.bs.dropdown', function(e){
    var $a  = $(e.target), is_a = $a.is('.is_a');
    if($a.hasClass('dropdown-toggle')){   
        $('ul.dropdown-menu', this).toggle(!is_a);
        $a.toggleClass('is_a', !is_a);
    }
}).on('mouseleave', function(){
    $('ul.dropdown-menu',this).hide();
    $('.is_a', this).removeClass('is_a');
});

Saya telah memperbaruinya sekali lagi untuk menjadi yang paling cerdas dan fungsional mungkin. sekarang tutup ketika Anda membawa di luar nav, tetap terbuka saat Anda berada di dalamnya. sempurna.

Luca Filosofi
sumber
Solusi Anda cerdas karena pendeknya, namun, setelah menambahkan kelas show, dropdown tidak menutup klik di luar, dan kita perlu mengklik pada dropdown-toggle sebelum ... +1 tetap
php-dev
saya telah memperbaruinya, lihat demo. itu adalah penyebab terbaik jangan mengecek acara klik tubuh setiap kali. hanya mempengaruhi elemen di dalam setiap elemen nav tunggal tidak di luar itu.
Luca Filosofi
Solusi saya juga tidak bergantung pada bodyklik event ^^
php-dev
ya, itu menyampaikan sebagian pada acara klik tubuh, itu mencoba untuk memeriksa elemen apa yang telah diklik melalui delegasi tubuh. $('body').on('click', function (e) {
Luca Filosofi
Tidak! Itu bukan jawaban saya. Jawaban saya adalah yang terakhir diposting.
php-dev
4

Seperti misalnya Bootstrap 4 Alpha memiliki Peristiwa Menu ini. Kenapa tidak digunakan?

// PREVENT INSIDE MEGA DROPDOWN
$('.dropdown-menu').on("click.bs.dropdown", function (e) {
    e.stopPropagation();
    e.preventDefault();                
});
Frank Thoeny
sumber
1
e.preventDefault();memblokir tautan, Anda dapat melewatinya
panjang
@czachor kau Benar! e.preventDefault (); Cegah tautan agar tidak mengikuti URL.
Frank Thoeny
3

Anda dapat menghentikan klik pada dropdown dari menyebarkan dan kemudian secara manual menerapkan kembali kontrol carousel menggunakan metode javascript carousel .

$('ul.dropdown-menu.mega-dropdown-menu').on('click', function(event) {
    event.stopPropagation();
});

$('a.left').click(function () {
    $('#carousel').carousel('prev');
});

$('a.right').click(function () {
    $('#carousel').carousel('next');
});

$('ol.carousel-indicators li').click(function (event) {
    var index = $(this).data("slide-to");
    $('#carousel').carousel(index);
});

Ini jsfiddle .

Neil
sumber
Contoh Anda berfungsi dengan baik tetapi masalahnya adalah bahwa dropdown dapat menampung konten apa pun dan tidak hanya gambar korsel ...
php-dev
3

Dengan Angular2 Bootstrap, Anda dapat menggunakan nonInput untuk sebagian besar skenario:

<div dropdown autoClose="nonInput">

nonInput - (default) secara otomatis menutup dropdown ketika salah satu elemennya diklik - selama elemen yang diklik bukanlah input atau textarea.

https://valor-software.com/ng2-bootstrap/#/dropdowns

Nir Soudry
sumber
2

Saya tahu pertanyaan ini khusus untuk jQuery, tetapi bagi siapa pun yang menggunakan AngularJS yang memiliki masalah ini, Anda dapat membuat arahan yang menangani ini:

angular.module('app').directive('dropdownPreventClose', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
          element.on('click', function(e) {
            e.stopPropagation(); //prevent the default behavior of closing the dropdown-menu
          });
        }
    };
});

Kemudian tambahkan saja atribut dropdown-prevent-closeke elemen Anda yang memicu menu untuk menutup, dan itu harus mencegahnya. Bagi saya, itu adalah selectelemen yang secara otomatis menutup menu:

<div class="dropdown-menu">
  <select dropdown-prevent-close name="myInput" id="myInput" ng-model="myModel">
    <option value="">Select Me</option>
  </select>
</div>
jtate
sumber
6
<div class="dropdown-menu" ng-click="$event.stopPropagation()">bekerja untuk saya di 1.2.x
dr3w
2

[Bootstrap 4 Alpha 6] [Rails] Untuk rel pengembang, e.stopPropagation()akan menyebabkan perilaku yang tidak diinginkan untuk link_todengan data-methodtidak sama untuk getkarena akan dengan kembali default semua permintaan Anda sebagai get.

Untuk mengatasi masalah ini, saya sarankan solusi ini, yang bersifat universal

$('.dropdown .dropdown-menu').on('click.bs.dropdown', function() {
  return $('.dropdown').one('hide.bs.dropdown', function() {
    return false;
  });
});

Jacky Tong
sumber
2

Alih-alih menulis beberapa kode javascript atau jquery (menciptakan kembali roda). Skenario di atas dapat dikelola dengan opsi tutup otomatis bootstrap. Anda dapat memberikan salah satu nilai untuk ditutup secara otomatis :

  1. always - (Default) secara otomatis menutup dropdown ketika salah satu elemennya diklik.

  2. outsideClick - menutup dropdown secara otomatis hanya ketika pengguna mengklik elemen apa pun di luar dropdown.

  3. dinonaktifkan - menonaktifkan penutupan otomatis

Lihatlah plunkr berikut:

http://plnkr.co/edit/gnU8M2fqlE0GscUQtCWa?p=preview

Set

uib-dropdown auto-close="disabled" 

Semoga ini membantu :)

ashwaniKumar
sumber
5
Harus secara eksplisit dicatat bahwa ini hanya baik untuk orang yang menggunakan ui-bootstrap, yang mungkin tidak berlaku untuk banyak orang yang melihat pertanyaan ini.
kevlarr
Anda dijelaskan dengan baik tetapi saya pikir Anda harus menulis solusi sebagai uib-dropdown auto-close="outsideClick". Menu tutup klik di dalam hanya sedikit ketidaknyamanan tetapi menu tidak tutup pada klik di luar cukup menjengkelkan.
vusan
2

Saya tahu sudah ada jawaban sebelumnya yang menyarankan untuk menggunakan formulir tetapi markup yang diberikan tidak benar / ideal. Inilah solusi termudah, tidak perlu javascript sama sekali dan tidak merusak dropdown Anda. Bekerja dengan Bootstrap 4.

<form class="dropdown-item"> <!-- Your elements go here --> </form>

Radu Ciobanu
sumber
@RosdiKasim Saya membuatnya bekerja dengan baik di situs web dengan Bootstrap 4.0.0. Belum diuji dengan 4.1
Radu Ciobanu
Sebenarnya seharusnya seperti: <form class = "dropdown dropdown-item">
Nasser Sadraee
2

Ini membantu saya,

$('.dropdown-menu').on('click', function (e) {
     if ($(this).parent().is(".open")) {
         var target = $(e.target);
         if (target.hasClass("keepopen") || target.parents(".keepopen").length){
                    return false; 
                }else{
                    return true;
                }
            }            
});

Elemen menu tarik turun Anda harus seperti ini, (catat kelas dropdown-menudan keepopen.

<ul role="menu" class="dropdown-menu topmenu-menu eserv_top_notifications keepopen">

Kode di atas mencegah pengunduhan pada keseluruhan <body>, sebagai gantinya ke elemen specfic dengan kelas dropdown-menu.

Semoga ini bisa membantu seseorang.

Terima kasih.

Anjana Silva
sumber
Terima kasih Diperbarui Seperti Per Bootstrap $ 4 ('. Menu dropdown [data-ditanganiropdownclose = "true"]'). On ('klik', fungsi (e) {if ($ (this) .parent (). Is (" .show ")) {var target = $ (e.target); return (target.hasClass (" CloseDropDown ") || target.parents (". CloseDropDown "). length);}});
Thulasiram
1

Solusi kerja paling sederhana bagi saya adalah:

  • menambahkan keep-open kelas ke elemen yang seharusnya tidak menyebabkan penutupan dropdown
  • dan bagian kode ini melakukan sisanya:
$('.dropdown').on('click', function(e) {
    var target = $(e.target);
    var dropdown = target.closest('.dropdown');
    return !dropdown.hasClass('open') || !target.hasClass('keep-open');
});
Astaga
sumber
bisa tolong bantu saya untuk memperbaiki ini stackoverflow.com/questions/51552712/… @ Gee-Bee
Zhu
1

Saya tidak menemukan satu pun solusi yang berfungsi karena saya ingin menggunakan nav bootstrap default. Ini solusi saya untuk masalah ini:

       $(document).on('hide.bs.dropdown', function (e) {
        if ($(e.currentTarget.activeElement).hasClass('dropdown-toggle')) {
          $(e.relatedTarget).parent().removeClass('open');
          return true;
        }
        return false;
       });
Mike
sumber
1

Dalam .dropdownkonten, letakkan .keep-openkelas pada label seperti ini:

$('.dropdown').on('click', function (e) {
    var target = $(e.target);
    var dropdown = target.closest('.dropdown');
    if (target.hasClass('keep-open')) {
        $(dropdown).addClass('keep-open');
    } else {
        $(dropdown).removeClass('keep-open');
    }
});

$(document).on('hide.bs.dropdown', function (e) {
    var target = $(e.target);
    if ($(target).is('.keep-open')) {
        return false
    }
});

Kasus-kasus sebelumnya menghindari peristiwa yang berkaitan dengan objek kontainer, sekarang wadah mewarisi kelas tetap terbuka dan periksa sebelum ditutup.

Dixán Santiesteban Feria
sumber
1

Saya melakukannya dengan ini:

$(element).on({
    'mouseenter': function(event) {
        $(event.currentTarget).data('mouseover', true);
    },
    'mouseleave': function(event) {
        $(event.currentTarget).data('mouseover', false);
    },
    'hide.bs.dropdown': function (event) {
        return !$(event.currentTarget).data('mouseover');
    }
});
William
sumber
0
$(function() {
    $('.mega-dropdown').on('hide.bs.dropdown', function(e) {
        var $target = $(e.target);
        return !($target.hasClass("keep-open") || $target.parents(".keep-open").size() > 0);
    });

    $('.mega-dropdown > ul.dropdown-menu').on('mouseenter', function() {
        $(this).parent('li').addClass('keep-open')
    }).on('mouseleave', function() {
        $(this).parent('li').removeClass('keep-open')
    });
});
SNC
sumber
0

Untuk menutup dropdown hanya jika acara klik dipicu di luar dropdown bootstrap, inilah yang bekerja untuk saya:

File JS:

    $('.createNewElement').on('click.bs.dropdown.data-api', '.tags-btn-group.keep-open-dropdown', function (e) {
        var target = $(e.target);
        if (target.hasClass("dropdown-menu") || target.parents(".dropdown-menu").length) {
            e.stopPropagation();
        }
    });

File HTML:

<!-- button: -->
<div class="createNewElement">
                <div class="btn-group tags-btn-group keep-open-dropdown">

                    <div class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">OPEN DROPDOWN</div>

                    <ul class="dropdown-menu">
                        WHAT EVER YOU WANT HERE...
                    </ul>

                </div>
</div>
Dudi
sumber
0

Anda mungkin memiliki beberapa masalah jika Anda menggunakan metode return false atau stopPropagation () karena acara Anda akan terputus. Coba kode ini, ini berfungsi dengan baik:

$(function() {
    $('.dropdown').on("click", function (e) {
            $('.keep-open').removeClass("show");
    });
    $('.dropdown-toggle').on("click", function () {
            $('.keep-open').addClass("show");
    });

    $( ".closeDropdown" ).click(function() {
        $('.dropdown').closeDropdown();
    });
});
jQuery.fn.extend({
    closeDropdown: function() {
        this.addClass('show')
            .removeClass("keep-open")
            .click()
            .addClass("keep-open");
    }
  });

Dalam HTML:

<div class="dropdown keep-open" id="search-menu" >
    <button  class="btn dropdown-toggle btn  btn-primary" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    <i class="fa fa-filter fa-fw"></i> 
    </button>
    <div class="dropdown-menu">
        <button class="dropdown-item" id="opt1" type="button">Option 1</button>
        <button class="dropdown-item" id="opt2" type="button">Option 2</button>
        <button type="button" class="btn btn-primary closeDropdown">Close</button>
    </div>
</div>

Jika Anda ingin menutup dropdrown:

`$('#search-menu').closeDropdown();`
Hchab
sumber
0

Di Bootstrap 4 Anda juga dapat melakukan ini:

$('#dd-link').on('hide.bs.dropdown', onListHide)

function onListHide(e)
{
  if(e.clickEvent && $.contains(e.relatedTarget.parentNode, e.clickEvent.target)) {
  e.preventDefault()
  }
}

di mana #dd-linkelemen jangkar atau tombol yang memiliki data-toggle="drowndown"properti.

Daniel
sumber