Как я могу закрыть поповертер Twitter Bootstrap одним щелчком мыши в любом месте на странице?

155

В настоящее время я использую всплывающие окна с Twitter Bootstrap, инициированные так:

$('.popup-marker').popover({
        html: true,
        trigger: 'manual'
    }).click(function(e) {
        $(this).popover('toggle');
        e.preventDefault();
    });

Как вы можете видеть, они запускаются вручную, и нажатие на .popup-marker (который является div с фоновым изображением) переключает всплывающее окно. Это прекрасно работает, но я хотел бы также иметь возможность закрыть поповер щелчком в любом месте на странице (но не на самом поповере!).

Я пробовал несколько разных вещей, в том числе следующие, но без результатов, чтобы показать это:

$('body').click(function(e) {
    $('.popup-marker').popover('hide');
});

Как закрыть поповер щелчком в любом месте на странице, но не нажатием на сам поповер?

Трэвис Норткатт
источник
Хм, я думаю, что это сработает ... У вас есть ссылка на это онлайн случайно?
thatryan

Ответы:

102

Предполагая, что только один поповер может быть виден в любое время, вы можете использовать набор флагов, чтобы пометить, когда есть поповер, и только потом скрыть их.

Если вы установите прослушиватель событий в теле документа, он будет срабатывать при нажатии на элемент, помеченный «popup-marker». Так что вам придется вызывать stopPropagation()объект события. И применить тот же трюк при нажатии на сам поповер.

Ниже приведен рабочий код JavaScript, который делает это. Использует jQuery> = 1.7

jQuery(function() {
    var isVisible = false;

    var hideAllPopovers = function() {
       $('.popup-marker').each(function() {
            $(this).popover('hide');
        });  
    };

    $('.popup-marker').popover({
        html: true,
        trigger: 'manual'
    }).on('click', function(e) {
        // if any other popovers are visible, hide them
        if(isVisible) {
            hideAllPopovers();
        }

        $(this).popover('show');

        // handle clicking on the popover itself
        $('.popover').off('click').on('click', function(e) {
            e.stopPropagation(); // prevent event for bubbling up => will not get caught with document.onclick
        });

        isVisible = true;
        e.stopPropagation();
    });


    $(document).on('click', function(e) {
        hideAllPopovers();
        isVisible = false;
    });
});

http://jsfiddle.net/AFffL/539/

Единственное предостережение в том, что вы не сможете открывать 2 поповера одновременно. Но я думаю, что это будет сбивать пользователя с толку :-)

Раду Кугут
источник
1
Нажатие на сам поповер в этом jsfiddle вызывает его скрытие - не совсем то, что просил tnorthcutt.
Джонатон Хилл
1
@RaduCugut это отличное решение. Но в этом есть ошибка. Нажмите один раз на zzzzz, и появится всплывающее окно. Теперь нажмите один раз на белом фоне. Всплывающее окно исчезает. Теперь нажмите еще раз на белом фоне. А теперь снова нажмите на zzzz, и он не работает. : - |
Хоуман
1
@ Кейв, вы правы, я изменил скрипку и ответ, чтобы исправить это. jsfiddle.net/AFffL/177
Раду Кугут
3
Почему бы просто не запустить $ ('. Popup-marker'). Popover ('hide') (чтобы скрыть их все) перед $ (this) .popover ('show'), что устраняет необходимость в любых переменных isVisible и clickedAway?
Натан Ханген,
1
Это решение вызвало у меня некоторые проблемы (нажатие на элемент «.popup-marker» открытого всплывающего окна привело к тому, что после этого всплывающие окна не работали). Я придумала еще одно решение (опубликовано ниже), которое работает для меня и кажется более простым (я использую Bootstrap 2.3.1).
RayOnAir
76

Это еще проще:

$('html').click(function(e) {
    $('.popup-marker').popover('hide');
});

$('.popup-marker').popover({
    html: true,
    trigger: 'manual'
}).click(function(e) {
    $(this).popover('toggle');
    e.stopPropagation();
});
prbaron
источник
Согласовано. И по крайней мере для меня это правильный способ сделать это. Первый вариант - «быстрое решение».
Денис Линс
4
Хотел использовать это, но по какой-то причине не сработало. События щелчков никогда не достигаются, htmlпотому что e.stopPropagation();вместо этого я использовал что-то вроде того, $('.popup-marker').on('show', function(event) { $('.popup-marker').filter(function(index, element) { return element != event.target; }).popover('hide'); });что тоже отлично справилось (не знаю, есть ли разница в производительности)
Cornelis
1
Это лучший ответ ИМО.
Loolooii
1
Компиляция ответов @pbaron и @Cornelis работает лучше всего. То, что я добавил, - это код Корнелиса внутри второй функции «щелчка» (непосредственно перед $(this).popover('toggle');деталью. Затем, если у вас есть несколько объектов «всплывающих маркеров», щелчок по каждому из них закроет остальные.
alekwisnia
2
Единственная проблема с этим - поповер все еще там, только скрытый. Так, например, если у вас есть ссылки во всплывающем окне, вы можете навести курсор на то место, где он был раньше, и при этом изменить курсор на этих ссылках.
Glacials
48

У меня была похожая потребность, и я нашел это отличное небольшое расширение Twitter Bootstrap Popover от Ли Кармайкла, названное BootstrapX - clickover . У него также есть несколько примеров использования здесь . В основном это изменит поповер на интерактивный компонент, который закроется, когда вы щелкнете в другом месте на странице или нажмете кнопку закрытия внутри всплывающего окна. Это также позволит одновременно открывать несколько всплывающих окон и множество других приятных функций.

Плагин можно найти здесь .

Пример использования

<button rel="clickover" data-content="Show something here. 
    <button data-dismiss='clickover'
    >Close Clickover</button>"
>Show clickover</button>

JavaScript:

// load click overs using 'rel' attribute
$('[rel="clickover"]').clickover();
Миика Л.
источник
1
Это действительно здорово. Супер просто.
Даг
Отличный плагин! Спасибо за ссылку.
Мэтт Уилсон
1
Просто дал ему шанс, и он прекрасно работает. Это было так же просто, как просто изменить существующую версию popover с «popover» на «clickover».
Dmase05
Запуск на Bootstrap v2.3.1, без проблем.
Кевин Дьюолт
37

Принятое решение вызвало у меня некоторые проблемы (щелчок по элементу «.popup-marker» открытого всплывающего окна заставил всплывающие окна не работать впоследствии). Я придумал другое решение, которое идеально подходит для меня, и оно довольно простое (я использую Bootstrap 2.3.1):

$('.popup-marker').popover({
    html: true,
    trigger: 'manual'
}).click(function(e) {
    $('.popup-marker').not(this).popover('hide');
    $(this).popover('toggle');
});
$(document).click(function(e) {
    if (!$(e.target).is('.popup-marker, .popover-title, .popover-content')) {
        $('.popup-marker').popover('hide');
    }
});

ОБНОВЛЕНИЕ: Этот код работает и с Bootstrap 3!

RayOnAir
источник
1
Это отличное решение. Спасибо.
Гэвин
1
Хорошее решение Почему бы вам не использовать if (!$(e.target).is('.popup-marker') && !$(e.target).parents('.popover').length > 0)этот способ, чтобы всплывающее окно не закрывалось, даже если в нем было html-содержимое
ykay говорит: «Восстановите Monica
2
Или лучшеif (!$(e.target).is('.popup-marker') && $(e.target).closest('.popover').length === 0)
fabdouglas
19

прочитайте "Уволить при следующем нажатии" здесь http://getbootstrap.com/javascript/#popovers

Вы можете использовать триггер фокусировки, чтобы отклонить всплывающие окна при следующем щелчке, но вы должны использовать <a>тег, а не <button>тег, и вы также должны включить tabindexатрибут ...

Пример:

<a href="#" tabindex="0" class="btn btn-lg btn-danger"
  data-toggle="popover" data-trigger="focus" title="Dismissible popover"
  data-content="And here's some amazing content. It's very engaging. Right?">
  Dismissible popover
</a>
Андрей Срамко
источник
2
В вопросе говорилось, что он не хотел, чтобы его уволили, если щелкнуть по поповеру. Это отклонит это на любом щелчке где угодно.
Фред
1
Добавление data-trigger = "focus" остановило запуск моих всплывающих окон, пока я не прочитал этот пост и не добавил атрибут tabindex. Теперь это работает!
PixelGraph
2
Для информации, это также работает tooltip, даже если это не указано явно в фактическом документе.
AlexB
7

Все существующие ответы довольно слабые, так как они основаны на захвате всех событий документа, затем на поиске активных всплывающих окон или изменении вызова .popover().

Гораздо лучший подход - слушать show.bs.popoverсобытия в теле документа, а затем реагировать соответствующим образом. Ниже приведен код, который будет закрывать всплывающие окна при щелчке или escнажатии документа, только привязывающие прослушиватели событий при отображении всплывающих окон:

function closePopoversOnDocumentEvents() {
  var visiblePopovers = [];

  var $body = $("body");

  function hideVisiblePopovers() {
    $.each(visiblePopovers, function() {
      $(this).popover("hide");
    });
  }

  function onBodyClick(event) {
    if (event.isDefaultPrevented())
      return;

    var $target = $(event.target);
    if ($target.data("bs.popover"))
      return;

    if ($target.parents(".popover").length)
      return;

    hideVisiblePopovers();
  }

  function onBodyKeyup(event) {
    if (event.isDefaultPrevented())
      return;

    if (event.keyCode != 27) // esc
      return;

    hideVisiblePopovers();
    event.preventDefault();
  }

  function onPopoverShow(event) {
    if (!visiblePopovers.length) {
      $body.on("click", onBodyClick);
      $body.on("keyup", onBodyKeyup);
    }
    visiblePopovers.push(event.target);
  }

  function onPopoverHide(event) {
    var target = event.target;
    var index = visiblePopovers.indexOf(target);
    if (index > -1) {
      visiblePopovers.splice(index, 1);
    }
    if (visiblePopovers.length == 0) {
      $body.off("click", onBodyClick);
      $body.off("keyup", onBodyKeyup);
    }
  }

  $body.on("show.bs.popover", onPopoverShow);
  $body.on("hide.bs.popover", onPopoverHide);
}
Дэвид Волевер
источник
+1 Это самое чистое и расширяемое решение. Если вы также используете фреймворк, такой как магистраль, просто поместите это в код инициализации, и он позаботится об обработке всплывающих окон.
JohnP
Этот ответ также добавляет проблемы производительности и позволяет обрабатывать более сложный HTML в поповере.
Рикардо
Отличное решение; был в состоянии бросить это в метод реакции довольно легко. Одно из предложений, добавьте $(event.target).data("bs.popover").inState.click = false;в функцию onPopoverHide, чтобы вам не нужно было дважды щелкать, чтобы снова открыться после закрытия.
sco_tt
Любопытно, если бы вы могли поиграть с этим двумя всплывающими окнами. В моем приложении, когда я реализовал ваш код, я смог щелкнуть всплывающее окно, чтобы всплывающее окно появилось несколько, а затем щелкнув «тело», удалил только последний отображенный.
Терри
2

По какой-то причине ни одно из других решений здесь не сработало для меня. Тем не менее, после многих проблем, я наконец-то пришел к этому методу, который работает идеально (по крайней мере, для меня).

$('html').click(function(e) {
  if( !$(e.target).parents().hasClass('popover') ) {
    $('#popover_parent').popover('destroy');
  }
});

В моем случае я добавлял поповер к таблице и абсолютно позиционировал его выше / ниже того, на tdкотором был нажат. Выбор таблицы был обработан с помощью jQuery-UI Selectable, поэтому я не уверен, что это мешало. Однако всякий раз, когда я нажимал внутри всплывающего окна, мой обработчик щелчков, который предназначался, $('.popover')никогда не работал, и обработка событий всегда делегировалась $(html)обработчику щелчков. Я довольно новичок в JS, так что, может быть, я что-то упустил?

В любом случае, я надеюсь, что это кому-то поможет!

moollaza
источник
Кстати, я не уверен, имеет ли это значение, но я использовал этот метод для Bootstrap 2. Я предполагаю, что он будет работать для Bootstrap 3, но не подтвердил.
moollaza
2

Я даю всем своим якорям поп-класса класс activate_popover. Я активирую их все одновременно

$('body').popover({selector: '.activate-popover', html : true, container: 'body'})

чтобы получить работающую функцию щелчка мышью (в сценарии кофе):

$(document).on('click', (e) ->
  clickedOnActivate = ($(e.target).parents().hasClass("activate-popover") || $(e.target).hasClass("activate-popover"))
  clickedAway = !($(e.target).parents().hasClass("popover") || $(e.target).hasClass("popover"))
if clickedAway && !clickedOnActivate
  $(".popover.in").prev().popover('hide')
if clickedOnActivate 
  $(".popover.in").prev().each () ->
    if !$(this).is($(e.target).closest('.activate-popover'))
      $(this).popover('hide')
)

Который прекрасно работает с начальной загрузкой 2.3.1

Берт-Ян Стирнеман
источник
Это сработало для меня, за исключением того, что я должен был избавиться от .prev() в первом ifпункте. Я использую Bootstrap 3.2.0.2, может есть разница? Кроме того, вы можете просто пропустить все второе ifпредложение, если хотите иметь возможность открывать несколько всплывающих окон одновременно. Просто щелкните в любом месте, которое не является элементом, активирующим popover (класс «activ-popover» в этом примере), чтобы закрыть все открытые всплывающие окна. Прекрасно работает!
Эндрю Свихарт
2

Несмотря на то, что здесь есть много решений, я хотел бы предложить и мое, я не знаю, есть ли какое-то решение, которое решает все это, но я попробовал 3 из них, и у них были проблемы, такие как нажатие на поповере он сам скрывает, другие, что если бы я нажал на другую поповерную кнопку, оба / несколько всплывающих окон все равно появлялись бы (как в выбранном решении), как бы то ни было, этот исправил все

var curr_popover_btn = null;
// Hide popovers function
function hide_popovers(e)
{
    var container = $(".popover.in");
    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
    {
        if( curr_popover_btn != null )
        {
            $(curr_popover_btn).popover('hide');
            curr_popover_btn = null;
        }
        container.hide();
    }
}
// Hide popovers when out of focus
$('html').click(function(e) {
    hide_popovers(e);
});
$('.popover-marker').popover({
    trigger: 'manual'
}).click(function(e) {
    hide_popovers(e);
    var $popover_btns = $('.popover-marker');
    curr_popover_btn = this;
    var $other_popover_btns = jQuery.grep($($popover_btns), function(popover_btn){
                return ( popover_btn !== curr_popover_btn );
            });
    $($other_popover_btns).popover('hide');
    $(this).popover('toggle');
    e.stopPropagation();
});
Рошди
источник
2

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

Код:

    $('.popup-marker').popover({
       html: true,
       trigger: 'manual'
    }).click(function(e) {
       $(this).popover('toggle');
       // set the focus on the popover itself 
       jQuery(".popover").attr("tabindex",-1).focus();
       e.preventDefault();
    });

    // live event, will delete the popover by clicking any part of the page
    $('body').on('blur','.popover',function(){
       $('.popup-marker').popover('hide');
    });
Лука Виззи
источник
1

Вот решение, которое работало очень хорошо для меня, если оно может помочь:

/**
* Add the equals method to the jquery objects
*/
$.fn.equals = function(compareTo) {
  if (!compareTo || this.length !== compareTo.length) {
    return false;
  }
  for (var i = 0; i < this.length; ++i) {
    if (this[i] !== compareTo[i]) {
      return false;
    }
  }
  return true;
};

/**
 * Activate popover message for all concerned fields
 */
var popoverOpened = null;
$(function() { 
    $('span.btn').popover();
    $('span.btn').unbind("click");
    $('span.btn').bind("click", function(e) {
        e.stopPropagation();
        if($(this).equals(popoverOpened)) return;
        if(popoverOpened !== null) {
            popoverOpened.popover("hide");            
        }
        $(this).popover('show');
        popoverOpened = $(this);
        e.preventDefault();
    });

    $(document).click(function(e) {
        if(popoverOpened !== null) {
            popoverOpened.popover("hide");   
            popoverOpened = null;
        }        
    });
});
Жиль Хеммерле
источник
1

Вот мое решение, для чего оно стоит:

// Listen for clicks or touches on the page
$("html").on("click.popover.data-api touchend.popover.data-api", function(e) {

  // Loop through each popover on the page
  $("[data-toggle=popover]").each(function() {

    // Hide this popover if it's visible and if the user clicked outside of it
    if ($(this).next('div.popover:visible').length && $(".popover").has(e.target).length === 0) {
      $(this).popover("hide");
    }

  });
});
ягодицы
источник
1

У меня были некоторые проблемы, чтобы заставить его работать на начальной загрузке 2.3.2. Но я решил это так:

$(function () {
  $(document).mouseup(function (e) {
        if(($('.popover').length > 0) && !$(e.target).hasClass('popInfo')) {
            $('.popover').each(function(){
                $(this).prev('.popInfo').popover('hide');
            });
        }
    });

    $('.popInfo').popover({
        trigger: 'click',
        html: true
    });
});
OBO
источник
1

немного подправил решение @David Wolever:

function closePopoversOnDocumentEvents() {
  var visiblePopovers = [];

  var $body = $("body");

  function hideVisiblePopovers() {
    /* this was giving problems and had a bit of overhead
      $.each(visiblePopovers, function() {
        $(this).popover("hide");
      });
    */
    while (visiblePopovers.length !== 0) {
       $(visiblePopovers.pop()).popover("hide");
    }
  }

  function onBodyClick(event) {
    if (event.isDefaultPrevented())
      return;

    var $target = $(event.target);
    if ($target.data("bs.popover"))
      return;

    if ($target.parents(".popover").length)
      return;

    hideVisiblePopovers();
  }

  function onBodyKeyup(event) {
    if (event.isDefaultPrevented())
      return;

    if (event.keyCode != 27) // esc
      return;

    hideVisiblePopovers();
    event.preventDefault();
  }

  function onPopoverShow(event) {
    if (!visiblePopovers.length) {
      $body.on("click", onBodyClick);
      $body.on("keyup", onBodyKeyup);
    }
    visiblePopovers.push(event.target);
  }

  function onPopoverHide(event) {
    var target = event.target;
    var index = visiblePopovers.indexOf(target);
    if (index > -1) {
      visiblePopovers.splice(index, 1);
    }
    if (visiblePopovers.length == 0) {
      $body.off("click", onBodyClick);
      $body.off("keyup", onBodyKeyup);
    }
  }

  $body.on("show.bs.popover", onPopoverShow);
  $body.on("hide.bs.popover", onPopoverHide);
}
Ли Гэри
источник
1

Этот вопрос также задавался здесь, и мой ответ предоставляет не только способ понять методы обхода JQuery DOM, но и 2 варианта обработки закрытия всплывающих окон, нажав снаружи.

Открывайте одновременно несколько всплывающих окон или по одному поповеру за раз.

Плюс эти небольшие фрагменты кода могут обрабатывать закрытие кнопок, содержащих значки!

https://stackoverflow.com/a/14857326/1060487

mattdlockyer
источник
1

Этот работает как шарм, и я использую его.

Он откроет всплывающее окно, когда вы щелкнете, и если вы нажмете еще раз, он закроется, также, если вы щелкнете за пределами всплывающего окна, всплывающее окно будет закрыто.

Это также работает с более чем 1 поповер.

    function hideAllPopovers(){
    $('[data-toggle="popover"]').each(function() {
        if ($(this).data("showing") == "true"){
            $(this).data("showing", "false");
            $(this).popover('hide');                
        }
    });
}
$('[data-toggle="popover"]').each(function() {
        $(this).popover({
            html: true,
            trigger: 'manual'
        }).click(function(e) {
            if ($(this).data("showing") !=  "true"){
                hideAllPopovers();
                $(this).data("showing", "true");
                $(this).popover('show');
            }else{
                hideAllPopovers();
            }
            e.stopPropagation();
        });
});

$(document).click(function(e) {
    hideAllPopovers();
});
Патрик Ногейра
источник
Это единственный, который работал на меня. Бутстрап 3.20. Спасибо.
Телегард
1

Другое решение, это покрыло проблему, которую я имел с щелчком потомков поповера:

$(document).mouseup(function (e) {
    // The target is not popover or popover descendants
    if (!$(".popover").is(e.target) && 0 === $(".popover").has(e.target).length) {
        $("[data-toggle=popover]").popover('hide');
    }
});
Фернандо Карабальо
источник
0

Я делаю это, как показано ниже

$("a[rel=popover]").click(function(event){
    if(event.which == 1)
    {   
        $thisPopOver = $(this);
        $thisPopOver.popover('toggle');
        $thisPopOver.parent("li").click(function(event){
            event.stopPropagation();
            $("html").click(function(){
                $thisPopOver.popover('hide');
            });
        });
    }
});

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

foxybagga
источник
0

Если вы пытаетесь использовать Twitter-загрузчик с pjax, это работает для меня:

App.Utils.Popover = {

  enableAll: function() {
    $('.pk-popover').popover(
      {
        trigger: 'click',
        html : true,
        container: 'body',
        placement: 'right',
      }
    );
  },

  bindDocumentClickEvent: function(documentObj) {
    $(documentObj).click(function(event) {
      if( !$(event.target).hasClass('pk-popover') ) {
        $('.pk-popover').popover('hide');
      }
    });
  }

};

$(document).on('ready pjax:end', function() {
  App.Utils.Popover.enableAll();
  App.Utils.Popover.bindDocumentClickEvent(this);
});
keruilin
источник
0

@RayOnAir, у меня та же проблема с предыдущими решениями. Я тоже близок к решению @RayOnAir. Одна вещь, которая улучшается, это закрыть уже открытый поповер при нажатии на другой маркер поповера. Итак, мой код:

var clicked_popover_marker = null;
var popover_marker = '#pricing i';

$(popover_marker).popover({
  html: true,
  trigger: 'manual'
}).click(function (e) {
  clicked_popover_marker = this;

  $(popover_marker).not(clicked_popover_marker).popover('hide');
  $(clicked_popover_marker).popover('toggle');
});

$(document).click(function (e) {
  if (e.target != clicked_popover_marker) {
    $(popover_marker).popover('hide');
    clicked_popover_marker = null;
  }
});
msa.im
источник
0

Я обнаружил, что это модифицированное решение вышеупомянутого предложения pbaron, потому что его решение активировало popover ('hide') для всех элементов с классом 'popup-marker'. Однако, когда вы используете popover () для html-контента вместо data-content, как я делаю ниже, любые щелчки внутри этого html-всплывающего окна фактически активируют popover ('hide'), который сразу закрывает окно. Приведенный ниже метод выполняет итерацию по каждому элементу .popup-marker и сначала обнаруживает, связан ли родительский элемент с идентификатором .popup-marker, по которому был выполнен щелчок, и, если это так, не скрывает его. Все остальные элементы скрыты ...

        $(function(){
            $('html').click(function(e) {
                // this is my departure from pbaron's code above
                // $('.popup-marker').popover('hide');
                $('.popup-marker').each(function() {
                    if ($(e.target).parents().children('.popup-marker').attr('id')!=($(this).attr('id'))) {
                        $(this).popover('hide');
                    }
                });
            });

            $('.popup-marker').popover({
                html: true,
                // this is where I'm setting the html for content from a nearby hidden div with id="html-"+clicked_div_id
                content: function() { return $('#html-'+$(this).attr('id')).html(); },
                trigger: 'manual'
            }).click(function(e) {
                $(this).popover('toggle');
                e.stopPropagation();
            });
        });
Дэвид
источник
0

Я придумал это:

Мой сценарий включал в себя больше всплывающих окон на одной странице, и их скрытие просто делало их невидимыми, и поэтому щелкать по элементам позади поповера было невозможно. Идея состоит в том, чтобы пометить конкретную ссылку popover как «активную», и тогда вы можете просто «переключить» активный popover. Это полностью закроет поповер.

$('.popover-link').popover({ html : true, container: 'body' })

$('.popover-link').popover().on 'shown.bs.popover', ->
  $(this).addClass('toggled')

$('.popover-link').popover().on 'hidden.bs.popover', ->
  $(this).removeClass('toggled')

$("body").on "click", (e) ->
  $openedPopoverLink = $(".popover-link.toggled")
  if $openedPopoverLink.has(e.target).length == 0
    $openedPopoverLink.popover "toggle"
    $openedPopoverLink.removeClass "toggled"
Ади Нистор
источник
0

Я пытался сделать простое решение для простой проблемы. Вышеупомянутые сообщения хороши, но так сложны для простого вопроса. Итак, я сделал простую вещь. Просто добавил кнопку закрытия. Это идеально подходит для меня.

            $(".popover-link").click(function(){
                $(".mypopover").hide();
                $(this).parent().find(".mypopover").show();
        })
        $('.close').click(function(){
    $(this).parents('.mypopover').css('display','none');
});



          <div class="popover-content">
        <i class="fa fa-times close"></i>
    <h3 class="popover-title">Title here</h3>
your other content here
        </div>


   .popover-content {
    position:relative;
    }
    .close {
        position:absolute;
        color:#CCC;
        right:5px;
        top:5px;
        cursor:pointer;
    }
Мохаммед Кашиф
источник
0

Мне нравится это, просто, но эффективно ..

var openPopup;

$('[data-toggle="popover"]').on('click',function(){
    if(openPopup){
        $(openPopup).popover('hide');

    }
    openPopup=this;
});
gstarr
источник
0

Добавьте btn-popoverкласс к вашей кнопке / ссылке на поповер, которая открывает поповер. Этот код закроет всплывающие окна при нажатии за его пределами.

$('body').on('click', function(event) {
  if (!$(event.target).closest('.btn-popover, .popover').length) {
    $('.popover').popover('hide');
  }
});
Тобиас Мюль
источник
0

Даже простое решение, просто перебрать все Popovers и шкурой , если не this.

$(document).on('click', '.popup-marker', function() {
    $(this).popover('toggle')
})

$(document).bind('click touchstart', function(e) {
    var target = $(e.target)[0];
    $('.popup-marker').each(function () {
        // hide any open popovers except for the one we've clicked
        if (!$(this).is(target)) {
            $(this).popover('hide');
        }
    });
});
inostia
источник
0
$('.popForm').popover();

$('.conteneurPopForm').on("click",".fermePopover",function(){
    $(".popForm").trigger("click");
});

Чтобы быть понятным, просто вызвать поповер

Poete
источник
0

Это должно работать в Bootstrap 4:

$("#my-popover-trigger").popover({
  template: '<div class="popover my-popover-content" role="tooltip"><div class="arrow"></div><div class="popover-body"></div></div>',
  trigger: "manual"
})

$(document).click(function(e) {
  if ($(e.target).closest($("#my-popover-trigger")).length > 0) {
    $("#my-popover-trigger").popover("toggle")
  } else if (!$(e.target).closest($(".my-popover-content")).length > 0) {
    $("#my-popover-trigger").popover("hide")
  }
})

Объяснение:

  • Первый раздел посвящен поповеру в соответствии с документами: https://getbootstrap.com/docs/4.0/components/popovers/
  • Первое «если» во втором разделе проверяет, является ли выбранный элемент потомком # my-popover-trigger. Если это правда, он переключает поповер (обрабатывает щелчок по триггеру).
  • Второе «если» во втором разделе проверяет, является ли выбранный элемент потомком класса контента popover, который был определен в шаблоне init. Если это не так, это означает, что щелчок не был внутри содержимого всплывающего окна, и всплывающее окно может быть скрыто.
Барт Взрыв
источник
Не могли бы вы уточнить ваш код? Добавить какое-то объяснение тому, что вы делаете?
Смертельный вальс
@DeathWaltz Я только что добавил объяснение в ответ.
Барт Blast
-1

Попробуй data-trigger="focus"вместо "click".

Это решило проблему для меня.

Ханнес
источник