Уникайте закритого меню, що закривається, при натисканні всередину


310

У мене є спадне меню завантаження Twitter. Як знають усі користувачі Twitter Bootstrap, випадаюче меню закривається при натисканні (навіть натисканні всередині нього).

Щоб уникнути цього, я можу легко долучити обробник подій клацання у спадному меню та просто додати відомий 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>

Це виглядає просто і дуже поширеною поведінкою, однак, оскільки carousel-controls(як і carousel indicators) обробники подій делеговані documentоб’єкту, clickподія на цих елементах ( попередні / наступні елементи керування, ...) буде «ігнорована».

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

Покладатися на Twitter Bootstrap випадаючі hide/ hiddenподії не є рішенням з наступних причин:

  • Наданий об'єкт події для обох обробників подій не посилається на клацнувший елемент
  • У мене немає контролю над вмістом випадаючого меню, тому додавання flagкласу чи атрибуту неможливо

Ця загадка - це нормальна поведінка, і ця загадка з event.stopPropagation()додаванням.

Оновлення

Дякую Роману за його відповідь . Я також знайшов відповідь, яку ви можете знайти нижче .


1. Ваш jsfiddle не працює. 2. Чого саме ви хочете досягти?
paulalexandru

1
@paulalexandru, Оновлено, додав дві скрипки. Одна поведінка за замовчуванням та одна з модифікацією. Спробуйте натиснути на наступну та попередню кнопку або на індикатори. У першому прикладі меню приховує & карусель слайди. або другий приклад: меню залишається відкритим, але карусель не ковзає з моменту event propagationзупинки.
php-dev

@paulalexandru Зрозумів, правда?
php-dev

@ php-dev: я оновив його знову заради виклику, тепер він ідеальний ... дивіться демонстрацію.
Лука Філософі

Відповіді:


373

Видалення атрибута даних data-toggle="dropdown" та реалізація відкритого / закриття випадаючого меню може бути рішенням.

Спочатку обробляючи клацання посилання, щоб відкрити / закрити спадне меню так:

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

а потім прослуховування клацань поза спадною панеллю, щоб закрити її так:

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

Ось демонстрація: http://jsfiddle.net/RomaLefrancois/hh81rhcm/2/


2
Це рішення працює чудово. Бонус повинен бути присуджений вам, якщо немає іншої відповіді.
php-dev

1
Ваше рішення є робочим, загальним, а також "популярним". Банду слід присвоїти вашій відповіді. Я також знайшов відповідь, подивіться на це нижче;)
php-dev

1
@Cichy ... просто змініть перший обробник на зразок цього ... $ ('li.dropdown.mega-dropdown a'). On ('click', function (event) {$ ('li.dropdown.mega-dropdown .open '). RemoveClass (' відкритий '); $ (this) .parent (). toggleClass (' open ');});
дсакет

63
Ця краща відповідь - хак. Ого!!! Ось простіший відповідь BOOTSTRAP 4 ALPHA, щоб запобігти клацанню всередині в мега-спаді. // PREVENT INSIDE CLICK DROPDOWN $('.dropdown-menu').on("click.bs.dropdown", function (e) { e.stopPropagation(); e.preventDefault(); });
Френк Тоні

7
e.stopPropagation()- найкраще рішення.
начолібр

332

Це також повинно допомогти

$(document).on('click', 'someyourContainer .dropdown-menu', function (e) {
  e.stopPropagation();
});

33
Я думаю, що це найпростіше рішення цієї проблеми. Великі пальці вгору - просто перевірено це, і воно працює!
Торстен Бартель

13
Це, безумовно, найкраще рішення.
мовчить

3
Це найпоширеніше рішення, але у мене є інша вимога. Будь ласка, уважно прочитайте моє запитання :)
php-dev

4
Найкраще рішення про просто збереження меню відкритим на кліки.
Метт Пірс

2
Справді, найкраще рішення. Я особисто використовував '.dropdown-menu :not(.dropdown-item)'так, що натискання на a dropdown-itemзакриває спливаюче вікно, а натискання на a dropdown-headerне робить.
Бенджамін

41

Bootstrap забезпечує таку функцію:

                 | Ця подія запускається негайно при використанні методу приховати примірник
hid.bs.dropdown | був покликаний. Перемикаючий анкерний елемент доступний як
                 | relatedTarget властивість події.

Тому, реалізуючи цю функцію, слід мати можливість відключити спадне закриття від закриття.

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

2
@Vartan, Також targetвластивістю події є li.dropdown, relatedTargetє a.dropdown-toggle. Таким чином, ви не можете звернутися до елемента, який натиснув, у межах hideобробника події.
php-dev

2
hasClass приймає ім'я класу, а не селектор CSS. target.hasClass(".keepopen")повинно бути target.hasClass("keepopen"). Інакше код не працюватиме.
Х'ю Гвіней

3
Я просканував Інтернет, і це найрозумніше рішення на сьогоднішній день, з цієї причини ... msot інші методи вимагають підходу, який використовує зупинку події за замовчуванням або зупинку розповсюдження. ці підходи дуже погані, оскільки вони порушують будь-які інші запускаються події всередині випадаючого меню (тобто елементи моєї форми jquery mobile) за допомогою цього підходу дозволяє конкретно визначити, коли саме меню закривається, і дозволять вам вжити заходів щодо цієї події самостійно. ця відповідь потребує стільки зірок ....
webfish

3
@webfish Скільки вам знадобилося сканувати Інтернет? (rofl)
php-dev

2
Можливо, це працювало .., але при завантажувальній програмі 4, e.target - це завжди саме спадне меню. Не націлену ціль. Навіть якщо натиснути за межі випадаючих списків, e.target все одно випадає. Таким чином, ви не можете виконати такий вид перевірки. Хтось бачить шлях до цього?
FredArters

36

Абсолютна найкраща відповідь - поставити тег форми після випадаючого меню класу

значить, ваш код

<ul class="dropdown-menu">
  <form>
    <li>
      <div class="menu-item">bla bla bla</div>
    </li>
  </form>
</ul>

2
функціонально працював чудово для мене, але порушив стайлінг
2778

2
це було найшвидшим рішенням для мене
Джонатан Моралес Велес

15
Це не найкраща відповідь :) <li>елемент не повинен бути всередині <form> елемента.
GETah

2
Це не семантично правильне рішення - єдиний дійсний дочірник UL - це LI - якщо щось теги форми повинні бути всередині тегів li - але це може не всеотримати бажану дію - інакше ul> form> li не є правильна розмітка
gavgrif

2
Думає про це швидке рішення
Герман Демсонг

27

Я також знайшов рішення.

Припускаючи, що Twitter Bootstrap Componentsвідповідні обробники подій делеговані documentоб’єкту, я петлю приєднані оброблювачі та перевіряю, чи відповідає поточний натиснутий елемент (або один з його батьків) делегованою подією.

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

Сподіваюсь, це допоможе тому, хто шукає подібне рішення.

Дякую всім за допомогу.


1
Ого!!! працював чудово! Тиждень був у біді, я використовую mCustomeScrollbar, і після натискання на панель прокрутки в спадному меню він закривав, ваш сценарій працював і тепер він працює нормально! Завдяки мільйонів.
eirenaios

працює чудово! як це розширити, щоб користувач міг ще натиснути клавішу "ESC" (або навіть натиснути зовні) на клавіатурі, щоб закрити DD?
Дядько Іро

2
@MaggewDotCom Натискання клавіші ESC все одно має працювати. Те саме для клацання на вулиці ...
php-dev

Єдиним недоліком цього рішення є те, що воно не дозволяє вкладені спадні місця (скажімо, у вас є крапля всередині спаду). Чи є спосіб вирішення цього випадку?
sdvnksv

26

Це може допомогти:

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

Це, безумовно, найпростіша / найкраща відповідь, якщо ви бажаєте, щоб користувач взаємодіяв з елементом інтерфейсу користувача, який присутній у спадному меню (наприклад, перемикачами), і не хочете, щоб меню закривалося під час переключення параметрів.
Роб

22
$('body').on("click", ".dropdown-menu", function (e) {
    $(this).parent().is(".open") && e.stopPropagation();
});

Це може спрацювати за будь-яких умов.


це має бути правильна відповідь, оскільки він використовує менше рядків коду, а не вибрану відповідь
Мухаммед Омер Аслам

@MuhammadOmerAslam Нах! Оскільки він не відповідає моїй вимозі
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>

Демонстрація :

Загальне: https://jsfiddle.net/kerryjohnson/omefq68b/1/

Ваша демонстрація цього рішення: http://jsfiddle.net/kerryjohnson/80oLdtbf/101/


9

Я спробував цю просту річ, і вона спрацювала як шарм.

Я змінив елемент спадного меню з <div>на, <form>і він добре працював.

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


6

У мене аналогічна проблема , в останній час і пробували різні способи її вирішення з видаленням атрибута даних data-toggle="dropdown"і прослуховування clickз event.stopPropagation()викликом.

Другий спосіб виглядає більш кращим. Також розробники Bootstrap використовують цей спосіб. У вихідному файлі я знайшов ініціалізацію випадаючих елементів:

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

Отже, цей рядок:

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

пропонує ви можете помістити formелемент всередині контейнера з класом, .dropdownщоб уникнути закриття випадаючого меню.


6

Bootstrap вирішив цю проблему самостійно, підтримуючи <form>теги у спадному меню. Їх рішення досить зрозуміле, і ви можете прочитати його тут: https://github.com/twbs/bootstrap/blob/v4-dev/js/src/dropdown.js

Він зводиться до запобігання розповсюдженню в документі елемента і робить це лише для подій типу, 'click.bs.dropdown.data-api'що відповідають селектору '.dropdown .your-custom-class-for-keep-open-on-click-elements'.

Або в коді

$(document).on('click.bs.dropdown.data-api', '.dropdown .keep-open-on-click', (event) => {
    event.stopPropagation();
});

1
Дякую, дякую, дякую за посилання на джерело. Іншим цікаво, чому formпідхід із прикладів не працює для вас - я використовував клас dropleft, але він також потрібен dropdownдля того, щоб селектор форм збігався.
Mark K Cowan

6

Я змінив відповідь @ Vartan, щоб вона працювала з Bootstrap 4.3. Його рішення більше не працює з останньою версією, оскільки targetвластивість завжди повертає корінь, що випадає, divнезалежно від того, де було розміщено клацання.

Ось код:

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

одна лінія:$('.dropdown-keep-open').on('hide.bs.dropdown', ev => !(ev.clickEvent && $(ev.target).has(ev.clickEvent.target).length))
Матвєєв Дмитро

@MatveevDmitriy Вибачте, але ніхто, просто ніхто не може прочитати цей лайнер. Написання коду таким чином є поганою практикою.
ViRuSTriNiTy

Останній рядок можна спростити за допомогою return !target.closest('.dropdown-keep-open').length). Однак, це чудове рішення! Виявив, що це потрібно для вирішення цієї проблеми.
patrick3853

6
$('body').on("click", ".dropdown-menu", function (e) {
    $(this).parent().is(".show") && e.stopPropagation();
});

По-перше, дякую за вашу відповідь. На питання вже відповіли. Також у мене є інша вимога, як описано в питанні, ніж загальна вимога.
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');
});

я оновив його ще раз, щоб бути найрозумнішим і функціональним, наскільки це можливо. тепер він закривається, коли ви наближаєтеся поза навігації, залишаючись відкритим, поки ви знаходитесь всередині нього. просто ідеально.


Ваше рішення розумне через його стислість, однак після додавання класу showспадне меню не закривається при натисканні назовні, і нам потрібно натиснути на перемикач, що випадає, перш ніж ... +1 все одно
php-dev

я оновив його, подивіться на демонстрацію. це найкраща причина, щоб не перевіряти події натискання тіла кожен раз. впливати тільки на елемент всередині кожного елемента елемента nav, а не поза ним.
Лука Філософі

Моє рішення також не покладається на bodyподії клацання ^^
php-dev

так, воно частково ретранслюється на подію натискання тіла, воно намагається перевірити, який елемент було натиснуто за допомогою делегації тіла. $('body').on('click', function (e) {
Лука Філософі

Ні! Це не моя відповідь. Моя відповідь - остання розміщена.
php-dev

4

Як, наприклад, Bootstrap 4 Alpha має це меню події. Чому б не використовувати?

// PREVENT INSIDE MEGA DROPDOWN
$('.dropdown-menu').on("click.bs.dropdown", function (e) {
    e.stopPropagation();
    e.preventDefault();                
});

1
e.preventDefault();блокує посилання, ви можете пропустити його
довгий

@czachor Ти маєш рацію! e.preventDefault (); Не дозволяйте посилання слідувати URL-адресою.
Френк Тоні

3

Ви можете зупинити натискання на спадне меню, що розповсюджується, а потім вручну повторно застосувати елементи каруселі за допомогою карусельних методів JavaScript .

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

Ось jsfiddle .


Ваш приклад працює чудово, але проблема полягає в тому, що випадаючий файл може вміщувати будь-який вміст, а не лише карусель зображень ...
php-dev

3

За допомогою Angular2 Bootstrap ви можете використовувати nonInput для більшості сценаріїв:

<div dropdown autoClose="nonInput">

nonInput - (за замовчуванням) автоматично закриває спадне меню при натисканні будь-якого з його елементів - до тих пір, поки клацнувший елемент не є входом або текстовою областю.

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


2

Я знаю, що це питання було розроблено спеціально для jQuery, але для тих, хто використовує AngularJS, у якого є ця проблема, ви можете створити директиву, яка займається цим:

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

Потім просто додайте атрибут dropdown-prevent-closeдо вашого елемента, який запускає меню для закриття, і він повинен запобігти. Для мене це був selectелемент, який автоматично закривав меню:

<div class="dropdown-menu">
  <select dropdown-prevent-close name="myInput" id="myInput" ng-model="myModel">
    <option value="">Select Me</option>
  </select>
</div>

6
<div class="dropdown-menu" ng-click="$event.stopPropagation()">працює для мене в 1.2.x
dr3w

2

[Bootstrap 4 Alpha 6] [Rails] Для розробника рейок e.stopPropagation()призведе до небажаної поведінки link_toз data-methodне рівним значенням, getоскільки воно за замовчуванням поверне весь ваш запит як get.

Для вирішення цієї проблеми я пропоную це рішення, яке є універсальним

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


2

Замість того щоб написати якийсь код JavaScript або jquery (винаходити колесо). Вищеописаним сценарієм можна керувати за допомогою функції автоматичного закриття завантажувача. Ви можете надати будь-яке значення для автоматичного закриття :

  1. завжди - (за замовчуванням) автоматично закриває спадне меню при натисканні будь-якого з його елементів.

  2. externalClick - закриває спадне меню автоматично лише тоді, коли користувач натискає будь-який елемент поза спадним меню.

  3. вимкнено - вимикає автоматичне закриття

Погляньте на наступний плункр:

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

Встановити

uib-dropdown auto-close="disabled" 

Сподіваюся, це допомагає :)


5
Слід чітко зазначити, що це добре лише для людей ui-bootstrap, які використовують , що, мабуть, не стосується дуже багатьох людей, які переглядають це питання.
kevlarr

Ви добре описали, але я думаю, ви повинні написати рішення як uib-dropdown auto-close="outsideClick". Закриття меню при натисканні всередині - лише невеликий дискомфорт, але меню, яке не закривається при натисканні назовні, дуже засмучує.
vusan

2

Я знаю, що вже є попередня відповідь, яка пропонує використовувати форму, але надана розмітка не є правильною / ідеальною. Ось найпростіше рішення, взагалі не потрібен JavaScript, і він не порушує ваш спадний список. Працює з Bootstrap 4.

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


@RosdiKasim У мене це добре працює на веб-сайті з Bootstrap 4.0.0. Не пройшов тестування з 4.1
Radu Ciobanu

Насправді це має бути так: <form class = "
dropdown drop

2

Це допомогло мені,

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

Елемент меню, що випадає, повинен мати такий вигляд (взяти до відома заняття dropdown-menuта keepopen.

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

Вищенаведений код запобігає встановленню ставок в цілому <body>, замість конкретного елемента з класомdropdown-menu .

Сподіваюся, що це комусь допоможе.

Дякую.


Дякуємо оновлено за завантаження 4 $ (". Спадне меню [data-handledropdownclose =" true "] '). On (' click ', функція (e) {if ($ (this) .parent (). Is (" .show ")) {var target = $ (e.target); return (target.hasClass (" CloseDropDown ") || target.parents (". CloseDropDown "). довжина);}});
Туласірам

1

Найпростіше для мене рішення:

  • додавання keep-openкласу до елементів, які не повинні викликати закриття спаду
  • і цей фрагмент коду робимо все інше:
$('.dropdown').on('click', function(e) {
    var target = $(e.target);
    var dropdown = target.closest('.dropdown');
    return !dropdown.hasClass('open') || !target.hasClass('keep-open');
});

чи можете ви допомогти мені виправити це stackoverflow.com/questions/51552712/… @ Gee-Bee
Чжу

1

Я не знайшов жодного з рішень, які працювали так, як я хотів би використовувати стандартний завантажувальний пристрій за замовчуванням. Ось моє рішення цієї проблеми:

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

1

За .dropdownзмістом кладіть .keep-openклас на будь-яку мітку так:

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

Попередні випадки уникали подій, пов’язаних з об'єктами контейнера, тепер контейнер успадковує клас "Keep-open" і перевіряє перед тим, як закрити.


1

Я зробив це з цим:

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

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

0

Для закриття випадаючого меню, лише якщо подія натискання була запущена поза спадною програмою завантаження, це для мене спрацювало:

Файл 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();
        }
    });

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>

0

У вас можуть виникнути проблеми, якщо ви використовуєте метод return false або stopPropagation (), оскільки ваші події будуть перервані. Спробуйте цей код, він працює чудово:

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

В 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>

Якщо ви хочете закрити падіння:

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

0

У Bootstrap 4 ви також можете це зробити:

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

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

де #dd-linkє елемент якоря або кнопка, яка має data-toggle="drowndown"властивість.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.