Arhn - архитектура программирования

Скрытие всплывающего окна Bootstrap при нажатии снаружи всплывающего окна

Я пытаюсь скрыть всплывающее окно Bootstrap, когда пользователь щелкает в любом месте за пределами всплывающего окна. (Я действительно не уверен, почему создатели Bootstrap решили не предоставлять эту функциональность.)

Я нашел следующий код: в Интернете, но я действительно этого не понимаю.

// Hide popover on click anywhere on the document except itself
$(document).click(function(e) {
    // Check for click on the popup itself
    $('.popover').click(function() {
        return false; // Do nothing
    });  
    // Clicking on document other than popup then hide the popup
    $('.pop').popover('hide');  
});

Главное, что меня смущает, это строка $('.popover').click(function() { return false; });. Разве эта строка не добавляет обработчик события клика? Как это препятствует тому, чтобы вызов popover('hide'), который следует за этим, скрывал всплывающее окно?

И кто-нибудь видел лучшую технику?

Примечание. Я знаю, что здесь уже задавались варианты этого вопроса, но ответы на эти вопросы включают более сложный код, чем код выше. Так что мой вопрос действительно о коде выше



Ответы:


1

Я сделал http://jsfiddle.net/BcczZ/2/, который, надеюсь, ответит на ваш вопрос.

Пример HTML

<div class="well>
    <a class="btn" data-toggle="popover" data-content="content.">Popover</a>
    <a class="btn btn-danger bad">Bad button</a>
</div>

JS

var $popover = $('[data-toggle=popover]').popover();

//first event handler for bad button
$('.bad').click(function () {
    alert("clicked");
});


$(document).on("click", function (e) {
    var $target = $(e.target),
    var isPopover = $target.is('[data-toggle=popover]'),
        inPopover = $target.closest('.popover').length > 0

    //Does nothing, only prints on console and wastes memory. BAD CODE, REMOVE IT
    $('.bad').click(function () { 
        console.log('clicked');
        return false;
    });

    //hide only if clicked on button or inside popover
    if (!isPopover && !inPopover) $popover.popover('hide');
});

Как я уже упоминал в своем комментарии, обработчики событий не перезаписываются, они просто складываются. Поскольку на кнопке .bad уже есть обработчик событий, он будет запущен вместе с любым другим обработчиком событий.

Откройте консоль в jsfiddle, нажмите 5 раз где-нибудь на странице (не кнопку всплывающего окна), а затем нажмите bad button, вы должны увидеть, что щелкнули напечатано столько же раз, сколько вы нажали

Надеюсь, поможет


P.S. Если подумать, вы уже видели, как это происходит, особенно в jQuery. Подумайте обо всех $(document).ready(...), которые существуют на странице с использованием нескольких плагинов jquery. Эта строка просто регистрирует обработчик события ready документа.

24.07.2013
  • Хорошо, спасибо за демонстрацию. Глядя на код, который я первоначально опубликовал тогда, он вряд ли кажется мне идеальным, поскольку я мог бы добавлять новый обработчик, который просто возвращает false в течение всего дня. Их может вырасти до любого количества, если страница не обновляется. Совсем не кажется идеальным. 25.07.2013
  • просто удалите код, который имеет дело с bad button, и используйте остальную часть моего кода. должно работать так, как вы этого хотите 25.07.2013

  • 2

    Я просто сделал решение, основанное на событиях.

    var $toggle = $('.your-popover-button');
    $toggle.popover();
    
    var hidePopover = function() {
        $toggle.popover('hide');
    };
    
    $toggle.on('shown', function () {
        var $popover = $toggle.next();
        $popover.on('mousedown', function(e) {
            e.stopPropagation();
        });
        $toggle.on('mousedown', function(e) {
            e.stopPropagation();
        });
        $(document).on('mousedown',hidePopover);
    });
    
    $toggle.on('hidden', function () {
        $(document).off('mousedown', hidePopover);
    });
    
    25.04.2014

    3

    короткий ответ вставьте это в загрузочный min.js

    когда всплывающее окно onblur будет скрывать всплывающее окно
    когда всплывающее окно более одного, старое всплывающее окно будет скрыто

    $count=0;$(document).click(function(evt){if($count==0){$count++;}else{$('[data-toggle="popover"]').popover('hide');$count=0;}});$('[data-toggle="popover"]').popover();$('[data-toggle="popover"]').on('click', function(e){$('[data-toggle="popover"]').not(this).popover('hide');$count=0;});
    
    08.09.2015

    4

    Ни одно из вышеперечисленных решений не сработало для меня на 100%, потому что мне пришлось дважды щелкнуть другое или одно и то же всплывающее окно, чтобы открыть его снова. Я написал решение с нуля, чтобы оно было простым и эффективным.

       $('[data-toggle="popover"]').popover({
            html:true,
            trigger: "manual",
            animation: false
        });
    
        $(document).on('click','body',function(e){
            $('[data-toggle="popover"]').each(function () {
                $(this).popover('hide');
            });
    
            if (e.target.hasAttribute('data-toggle') && e.target.getAttribute('data-toggle') === 'popover') {
                e.preventDefault();
                $(e.target).popover('show');
            }
            else if (e.target.parentElement.hasAttribute('data-toggle') && e.target.parentElement.getAttribute('data-toggle') === 'popover') {
                e.preventDefault();
                $(e.target.parentElement).popover('show');
            }
        });
    
    11.05.2017

    5

    Мое решение работает на 100% для Bootstrap v3

    $('html').on('click', function(e) {
        if(typeof $(e.target).data('original-title') !== 'undefined'){
             $('[data-original-title]').not(e.target).popover('hide');
        }
    
        if($(e.target).parents().is('[data-original-title]')){
             $('[data-original-title]').not($(e.target).closest('[data-original-title]')).popover('hide');
        }
    
        if (typeof $(e.target).data('original-title') == 'undefined' &&
    !$(e.target).parents().is('.popover.in') && !$(e.target).parents().is('[data-original-title]')) {
            $('[data-original-title]').popover('hide');
        }
    });
    
    25.04.2018
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..