Jak zamknąć popover Twitter Bootstrap, klikając na zewnątrz?

289

Czy możemy sprawić, by popovers były usuwalne w taki sam sposób jak modały, tj. zamknąć je, gdy użytkownik kliknie gdzieś poza nimi?

Niestety nie mogę po prostu użyć prawdziwego modalu zamiast popovera, ponieważ modal oznacza position: fixed i nie byłoby już popovera. :(

Ante Vrli
źródło
3
Podobne pytanie: stackoverflow.com/q/8947749/1478467
Sherbrow
Spróbuj tego stackoverflow.com/a/40661543/5823517 . Nie wymaga zapętlania rodziców
Tunn,
data-trigger="hover"i data-trigger="focus"są wbudowaną alternatywą do zamykania okna popover, jeśli nie chcesz używać przełącznika. Moim zdaniem data-trigger="hover"zapewnia najlepsze wrażenia użytkownika ... nie ma potrzeby pisania dodatkowego kodu .js ...
Hooman Bahreini 24.04.2019

Odpowiedzi:

461

Aktualizacja: nieco bardziej niezawodne rozwiązanie: http://jsfiddle.net/mattdlockyer/C5GBU/72/

W przypadku przycisków zawierających tylko tekst:

$('body').on('click', function (e) {
    //did not click a popover toggle or popover
    if ($(e.target).data('toggle') !== 'popover'
        && $(e.target).parents('.popover.in').length === 0) { 
        $('[data-toggle="popover"]').popover('hide');
    }
});

W przypadku przycisków zawierających ikony (ten kod zawiera błąd w programie Bootstrap 3.3.6, zobacz poprawkę poniżej w tej odpowiedzi)

$('body').on('click', function (e) {
        //did not click a popover toggle, or icon in popover toggle, or popover
        if ($(e.target).data('toggle') !== 'popover'
            && $(e.target).parents('[data-toggle="popover"]').length === 0
            && $(e.target).parents('.popover.in').length === 0) { 
            $('[data-toggle="popover"]').popover('hide');
        }
    });

Dla JS Generowane Popovers Użyj '[data-original-title]'zamiast'[data-toggle="popover"]'

Zastrzeżenie: powyższe rozwiązanie umożliwia otwieranie wielu popoverów jednocześnie.

Jeden popover na raz:

Aktualizacja: Bootstrap 3.0.x, zobacz kod lub skrzypce http://jsfiddle.net/mattdlockyer/C5GBU/2/

$('body').on('click', function (e) {
    $('[data-toggle="popover"]').each(function () {
        //the 'is' for buttons that trigger popups
        //the 'has' for icons within a button that triggers a popup
        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
            $(this).popover('hide');
        }
    });
});

To obsługuje zamykanie okien pop-up, które są już otwarte i nie kliknięte lub ich łącza nie zostały kliknięte.


Aktualizacja: Bootstrap 3.3.6, patrz skrzypce

Naprawiono problem polegający na tym, że po zamknięciu potrzeba 2 kliknięć, aby ponownie otworzyć

$(document).on('click', function (e) {
    $('[data-toggle="popover"],[data-original-title]').each(function () {
        //the 'is' for buttons that trigger popups
        //the 'has' for icons within a button that triggers a popup
        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {                
            (($(this).popover('hide').data('bs.popover')||{}).inState||{}).click = false  // fix for BS 3.3.6
        }

    });
});

Aktualizacja: Wykorzystując warunek poprzedniego ulepszenia, to rozwiązanie zostało osiągnięte. Napraw problem podwójnego kliknięcia i wyskakującego widma:

$(document).on("shown.bs.popover",'[data-toggle="popover"]', function(){
    $(this).attr('someattr','1');
});
$(document).on("hidden.bs.popover",'[data-toggle="popover"]', function(){
    $(this).attr('someattr','0');
});
$(document).on('click', function (e) {
    $('[data-toggle="popover"],[data-original-title]').each(function () {
        //the 'is' for buttons that trigger popups
        //the 'has' for icons within a button that triggers a popup
        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
            if($(this).attr('someattr')=="1"){
                $(this).popover("toggle");
            }
        }
    });
});
mattdlockyer
źródło
2
Załączam $(document)zamiast, $('body')ponieważ czasami bodynie rozciąga się na całą stronę.
jasop
6
Po aktywowaniu programu popover (i późniejszej akcji ukrywania), program popover nie jest całkowicie ukryty; to po prostu nie jest widoczne. Problem polega na tym, że nie można kliknąć ani ukryć treści pod niewidocznym, ale obecnym pop-upem. Problem występuje w najnowszej kompilacji Chrome, najnowszym bootstrapie 3 .js (mogą to być również inne przeglądarki, nie można się tym
martwić,
6
Zamiast '[data-toggle="popover"]', który nie działa z popoverami generowanymi w JavaScript, użyłem '[data-original-title]'jako selektora.
Nathan
4
Czy ktoś wie, dlaczego to rozwiązanie nie działa z najnowszą wersją bootstrap? Dzieje się tak: Kliknij przycisk, aby wyświetlić okno podręczne, następnie kliknij ciało, aby je zamknąć, a następnie kliknij przycisk, aby wyświetlić okno podręczne, a okno podręczne się nie wyświetla. Po niepowodzeniu, jeśli klikniesz go ponownie, wyświetli się. To jest bardzo dziwne.
JTunney
3
@JTunney Korzystam z wersji BS 3.3.6 i nadal widzę takie zachowanie, które wymaga dwóch kliknięć, aby otworzyć popoever po odrzuceniu jednego.
sersun
65
$('html').on('mouseup', function(e) {
    if(!$(e.target).closest('.popover').length) {
        $('.popover').each(function(){
            $(this.previousSibling).popover('hide');
        });
    }
});

Spowoduje to zamknięcie wszystkich okien wyskakujących, jeśli klikniesz w dowolnym miejscu oprócz okna wyskakującego

AKTUALIZACJA Bootstrap 4.1

$("html").on("mouseup", function (e) {
    var l = $(e.target);
    if (l[0].className.indexOf("popover") == -1) {
        $(".popover").each(function () {
            $(this).popover("hide");
        });
    }
});
użytkownik 28490
źródło
Dodałem klasę do przycisku, który uruchamia popover (pop-btn), więc nie jest uwzględniony ... if (! $ (E.target) .closest ('. Popover'). Length &&! $ (E. target) .closest ('. btn'). hasClass ('pop-btn'))
mozgras
2
z 3 przyciskami popover ten kod sprawia problemy. w niektórych przypadkach nie mogę kliknąć przycisku, a przyciski migają.
OpenCode
1
Nie mogę uruchomić tego kodu ... sprawdź to skrzypce i dodaj skrzypce do swojej odpowiedzi. jsfiddle.net/C5GBU/102
mattdlockyer
Idealne dla mnie. Inne odpowiedzi miały skutki uboczne, kiedy moje „kliknięcie z zewnątrz” zdarzyło się otworzyć nowe okno popover.
Facio Ratio
Działa to świetnie, ale musi mieć sposób na dostosowanie tego, aby kliknięcie zawartości okna popover nie zamknęło się. np. jeśli klikniesz tekst wewnątrz znacznika <b> w oknie popover ...
Ben w Kalifornii
39

Najprostsza, najbardziej odporna na awarie wersja , działa z każdą wersją bootstrap.

Demo: http://jsfiddle.net/guya/24mmM/

Demo 2: Nie odrzuca się po kliknięciu wewnątrz zawartości popover http://jsfiddle.net/guya/fjZja/

Demo 3: Wiele popovers: http://jsfiddle.net/guya/6YCjW/


Samo wywołanie tej linii spowoduje odrzucenie wszystkich popoverów:

$('[data-original-title]').popover('hide');

Odrzuć wszystkie okna wyskakujące po kliknięciu na zewnątrz za pomocą tego kodu:

$('html').on('click', function(e) {
  if (typeof $(e.target).data('original-title') == 'undefined') {
    $('[data-original-title]').popover('hide');
  }
});

Fragment powyżej dołącza zdarzenie kliknięcia do treści. Gdy użytkownik kliknie popovera, będzie on zachowywał się normalnie. Kiedy użytkownik kliknie na coś, co nie jest popover, zamknie wszystkie popovers.

Będzie również działał z popoverami, które są inicjowane przez Javascript, w przeciwieństwie do niektórych innych przykładów, które nie będą działać. (patrz demo)

Jeśli nie chcesz odrzucić, klikając wewnątrz zawartości popover, użyj tego kodu (patrz link do 2. wersji demo):

$('html').on('click', function(e) {
  if (typeof $(e.target).data('original-title') == 'undefined' && !$(e.target).parents().is('.popover.in')) {
    $('[data-original-title]').popover('hide');
  }
});
guya
źródło
3
Miałem podobny problem i działało to w Bootstrap 3.
wsams
Jeśli zbliżysz okna popover do siebie, aby się nakładały, po ukryciu okna popover klikając gdzieś na zewnątrz, jeden z łączy przestaje działać. Sprawdź: jsfiddle.net/qjcuyksb/1
Sandeep Giri
1
Ostatnia wersja nie działa, gdy używasz bootstrap-datepicker w popover.
dbinott,
1
Najbardziej podobało mi się to rozwiązanie, ponieważ zaakceptowana odpowiedź zaczęła być jak świnia zasobów z około 30 wyskakującymi oknami
David G
1
Być może !$(e.target).closest('.popover.in').lengthbyłby bardziej wydajny niż !$(e.target).parents().is('.popover.in').
joeytwiddle
19

W bootstrap 2.3.2 możesz ustawić wyzwalacz na „focus” i to po prostu działa:

$('#el').popover({trigger:'focus'});
periklis
źródło
1
+1, ale ważna uwaga dodatkowa: To nie zamyka okna popover, jeśli ponownie klikniesz przycisk lub kotwicę, a zaakceptowana odpowiedź tak.
Christian Gollhardt,
18

Zasadniczo nie jest to zbyt skomplikowane, ale należy wykonać pewne czynności kontrolne, aby uniknąć usterki.

Demo (jsfiddle)

var $poped = $('someselector');

// Trigger for the popover
$poped.each(function() {
    var $this = $(this);
    $this.on('hover',function() {
            var popover = $this.data('popover');
            var shown = popover && popover.tip().is(':visible');
            if(shown) return;        // Avoids flashing
            $this.popover('show');
    });
});

// Trigger for the hiding
 $('html').on('click.popover.data-api',function() {
    $poped.popover('hide');
});
Sherbrow
źródło
2
to odrzuca modalność, klikając wszędzie nie na zewnątrz
hienbt88,
Czy można to zrobić za pomocą popover()kliknięcia zamiast najechania kursorem?
Zaki Aziz,
3
Oczywiście, ale musisz wywołać stopPropagation()zdarzenie przekazane do modułu obsługi kliknięć (jeśli nie, ukryty moduł obsługi natychmiast ukrywa popover). Demo (jsfiddle)
Sherbrow
Mam tę samą funkcjonalność poniżej w znacznie mniejszym kodzie. Ta odpowiedź jest rozdęta i nieco niedorzeczna, jeśli chodzi o pytanie ... Wszystko, czego chce, to zamykać okna popover po kliknięciu na zewnątrz ... To przesada i Brzydki!
mattdlockyer
2
Korekta, wierzę, że mam LEPSZĄ funkcjonalność w DALSZYM kodzie. Zakłada się, że chcesz wyświetlać tylko jedno okienko naraz. Jeśli Ci się spodoba, proszę upomnieć się o moją odpowiedź poniżej: jsfiddle.net/P3qRK/1 odpowiedź: stackoverflow.com/a/14857326/1060487
mattdlockyer
16

Żadne z rzekomo wysoko głosowanych rozwiązań nie działało dla mnie poprawnie. Każda z nich powoduje błąd, gdy po otwarciu i zamknięciu (klikając inne elementy) popover po raz pierwszy nie otwiera się ponownie, dopóki nie utworzysz dwóch klikniesz linku wyzwalającego zamiast jednego.

Więc nieznacznie go zmodyfikowałem:

$(document).on('click', function (e) {
    var
        $popover,
        $target = $(e.target);

    //do nothing if there was a click on popover content
    if ($target.hasClass('popover') || $target.closest('.popover').length) {
        return;
    }

    $('[data-toggle="popover"]').each(function () {
        $popover = $(this);

        if (!$popover.is(e.target) &&
            $popover.has(e.target).length === 0 &&
            $('.popover').has(e.target).length === 0)
        {
            $popover.popover('hide');
        } else {
            //fixes issue described above
            $popover.popover('toggle');
        }
    });
})
Anton Siergiejew
źródło
1
Fajnie, to działa dla mnie. BTW zapomniałeś a); na końcu kodu po ostatnim}
Merlin
1
Miał ten sam problem związany z drugim kliknięciem. To powinna być bezpieczna odpowiedź!
Felipe Leão
Próbowałem również poprzednich rozwiązań powyżej, ale jako wskazówka dla tych, którzy szukają rozwiązania od 2016 roku, jest to lepsze rozwiązanie.
dariru
najlepsza odpowiedź, działa jak w reklamie. jak wspomniano, inni nie. to powinna być najlepsza odpowiedź
duggi
Działa idealnie, ale nie użyłem data-toggel = "popover". Możesz jednak określić dowolny selektor pasujący do elementów wyzwalacza popover. Dobre rozwiązanie i jedyne, które rozwiązało problem dwóch kliknięć.
shock_gone_wild
11

Zrobiłem jsfiddle, aby pokazać ci, jak to zrobić:

http://jsfiddle.net/3yHTH/

Chodzi o to, aby pokazać popover po kliknięciu przycisku i ukryć popover po kliknięciu poza przyciskiem.

HTML

<a id="button" href="#" class="btn btn-danger">Click for popover</a>

JS

$('#button').popover({
    trigger: 'manual',
    position: 'bottom',
    title: 'Example',
    content: 'Popover example for SO'
}).click(function(evt) {
    evt.stopPropagation();
    $(this).popover('show');
});

$('html').click(function() {
    $('#button').popover('hide');
});
Pigueiras
źródło
niezłe demo. Zastanawiam się, jak można wywołać popover na obiekcie Jquery, popover jest wtyczką bootstrap js, ale nie ma tam pliku js bootstrap?
bingjie2680,
W pliku jsfiddle znajduje się plik js. Spójrz na lewą kolumnę -> Zarządzaj zasobami.
Pigueiras
Ok, widzę, że jest js bootstrap. ale nie jest zaznaczone, nadal działa?
bingjie2680
Tak to działa. W każdym razie szukałem w google: jsfiddle bootstrapi dał mi szkielet bootstrap css + js w jsfiddle.
Pigueiras
2
Moim jedynym problemem jest to, że ukrywasz popover po kliknięciu. Równie dobrze może po prostu użyć podpowiedzi.
NoBrainer
6

po prostu dodaj ten atrybut do elementu

data-trigger="focus"
Siraj K.
źródło
Początkowo nie działało to dla mnie z Bootstrap 3.3.7, ale potem przeczytałem dokumenty i mają one pewne wskazówki, o których warto tutaj wspomnieć. Z przykładu Dismiable popover w dokumentach „Aby zachować prawidłowe działanie w różnych przeglądarkach i na różnych platformach, musisz użyć tagu <a>, a nie tagu <button>, a także musisz dołączyć atrybuty role =" button "i tabindex . ”
Jeff
3

Ten został poproszony przed tutaj . Ta sama odpowiedź, którą podałem, nadal obowiązuje:

Miałem podobną potrzebę i znalazłem to świetne małe rozszerzenie Twitter Bootstrap Popover autorstwa Lee Carmichaela, o nazwie BootstrapX - kliknięcie . Ma też kilka przykładów wykorzystania tutaj . Zasadniczo zmieni popover w interaktywny komponent, który zamknie się po kliknięciu w inne miejsce strony lub na przycisku zamykania w popover. Umożliwi to również otwieranie wielu okien pop-up jednocześnie i wiele innych ciekawych funkcji.

Miika L.
źródło
3

Na przyjęcie jest już późno ... ale pomyślałem, że się z tym podzielę. Uwielbiam popover, ale ma tak mało wbudowanej funkcjonalności. Napisałem rozszerzenie bootstrap .bubble (), czyli wszystko, co chciałbym, żeby był popover. Cztery sposoby na zwolnienie. Kliknij na zewnątrz, przełącz na link, kliknij X i naciśnij Escape.

Ustawia się automatycznie, więc nigdy nie znika ze strony.

https://github.com/Itumac/bootstrap-bubble

To nie jest nieodpłatna autopromocja ... Wiele razy w życiu chwytałem kod innych ludzi, chciałem zaoferować własne wysiłki. Daj mu wir i sprawdź, czy to działa dla Ciebie.

Itumac
źródło
3

Według http://getbootstrap.com/javascript/#popovers ,

<button type="button" class="popover-dismiss" data-toggle="popover" title="Dismissible popover" data-content="Popover Content">Dismissible popover</button>

Użyj wyzwalacza aktywności, aby odrzucić wyskakujące okienka przy następnym kliknięciu, które wykona użytkownik.

$('.popover-dismiss').popover({
    trigger: 'focus'
})
effe
źródło
2
Nie działa w przeglądarkach komputerów Mac zgodnych z natywnym zachowaniem OS X (które nie ustawiają ostrości ani nie rozmywają przycisków po kliknięciu). Należą do nich Firefox i Safari. Faceci Bootstrap popełnili tutaj duży błąd, ponieważ tych popoverów nie można nawet otworzyć, nie mówiąc już o ich odrzuceniu.
Ante Vrli
2
@AnteVrli Może to nie był jeszcze w dokumentacji, kiedy pisał swój komentarz ale teraz docs powiedzieć: „Dla prawidłowego przekroju przeglądarce i zachowania cross-platform, należy użyć <a>znacznika, a nie <button>etykiety, a także musi zawierać role="button"i tabindexatrybuty ”. Czy próbowałeś tego z tymi specyfikacjami?
Louis
3
Cóż, jest problem z tą odpowiedzią, który nie ma nic wspólnego ze zgodnością platformy: naciśnięcie przycisku myszy w oknie popover spowoduje jego zamknięcie, ponieważ element, który je uruchamia, straci fokus. Zapomnij, że użytkownicy mogą kopiować i wklejać z okien popover: jak tylko przycisk myszy jest wciśnięty, okno zamykające się zamyka. Jeśli masz elementy, które można wykonać w oknie popover (przyciski, linki), użytkownicy nie będą mogli ich używać.
Louis
Tyle o „wieloplatformowym”, ponieważ w bootstrap 4.0.0-beta i 4.0.0-beta.2 nie mogę tego uruchomić na komputerze Mac w Chrome :(
rmcsharry
3

Zmodyfikowane zaakceptowane rozwiązanie. To, czego doświadczyłem, to fakt, że po ukryciu niektórych programów typu popover trzeba je dwukrotnie kliknąć, aby wyświetlić się ponownie. Oto, co zrobiłem, aby upewnić się, że popover („hide”) nie jest wywoływany w już ukrytych popoverach.

$('body').on('click', function (e) {
    $('[data-original-title]').each(function () {
        //the 'is' for buttons that trigger popups
        //the 'has' for icons within a button that triggers a popup
        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
            var popoverElement = $(this).data('bs.popover').tip();
            var popoverWasVisible = popoverElement.is(':visible');

            if (popoverWasVisible) {
                $(this).popover('hide');
                $(this).click(); // double clicking required to reshow the popover if it was open, so perform one click now
            }
        }
    });
});
Chisom Daniel Mba
źródło
3

To rozwiązanie działa dobrze:

$("body")   .on('click'     ,'[data-toggle="popover"]', function(e) { 
    e.stopPropagation();
});

$("body")   .on('click'     ,'.popover' , function(e) { 
     e.stopPropagation();
});

$("body")   .on('click'  , function(e) {
        $('[data-toggle="popover"]').popover('hide');
});
LN
źródło
2
jQuery("#menu").click(function(){ return false; });
jQuery(document).one("click", function() { jQuery("#menu").fadeOut(); });
hienbt88
źródło
2

Możesz także użyć opcji bubbingu zdarzeń, aby usunąć wyskakujące okienko z DOM. Jest trochę brudny, ale działa dobrze.

$('body').on('click touchstart', '.popover-close', function(e) {
  return $(this).parents('.popover').remove();
});

W swoim html dodaj klasę .popover-close do treści w oknie popover, które powinno je zamknąć.

Hendrik
źródło
2

Wygląda na to, że metoda „ukryj” nie działa, jeśli utworzysz popover z delegacją selektora, zamiast tego należy użyć opcji „zniszczyć”.

Sprawiłem, że działa tak:

$('body').popover({
    selector: '[data-toggle="popover"]'
});

$('body').on('click', function (e) {
    $('[data-toggle="popover"]').each(function () {
        //the 'is' for buttons that trigger popups
        //the 'has' for icons within a button that triggers a popup
        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
            $(this).popover('destroy');
        }
    });
});

JSfiddle tutaj

Vladimir Dimchev
źródło
2

Dowiedzieliśmy się, że mamy problem z rozwiązaniem @mattdlockyer (dzięki za rozwiązanie!). Podczas korzystania z właściwości selektora dla konstruktora popover w ten sposób ...

$(document.body').popover({selector: '[data-toggle=popover]'});

... proponowane rozwiązanie dla BS3 nie będzie działać. Zamiast tego tworzy drugą instancję popover lokalną dla niego $(this). Oto nasze rozwiązanie, aby temu zapobiec:

$(document.body).on('click', function (e) {
    $('[data-toggle="popover"]').each(function () {
        //the 'is' for buttons that trigger popups
        //the 'has' for icons within a button that triggers a popup
        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
            var bsPopover = $(this).data('bs.popover'); // Here's where the magic happens
            if (bsPopover) bsPopover.hide();
        }
    });
});

Jak wspomniano $(this).popover('hide');, utworzy drugą instancję z powodu delegowanego odbiornika. Podane rozwiązanie ukrywa tylko pop-upy, które są już zaimplementowane.

Mam nadzieję, że zaoszczędzę wam trochę czasu.

jądro
źródło
2

Bootstrap natywnie obsługuje to :

JS Bin Demo

Określony znacznik wymagany do odwołania przy następnym kliknięciu

Dla prawidłowego przekroju przeglądarce i zachowania cross-platform, należy użyć <a>znacznika, nie<button> znacznika, a także musi zawierać role="button"i tabindexatrybuty.

Tanner Perrien
źródło
W bootstrap 4.0.0-beta i 4.0.0-beta.2 nie mogę tego uruchomić na Macu w Chrome :(
rmcsharry
Kliknięcie w dowolnym miejscu zamyka ten popover, pytający wymaga „kliknięcie poza popover zamyka go”, co jest inne.
philw
2

to rozwiązanie pozwala pozbyć się przykrych, drugich kliknięć podczas wyświetlania popovera po raz drugi

testowane z Bootstrap v3.3.7

$('body').on('click', function (e) {
    $('.popover').each(function () {
        var popover = $(this).data('bs.popover');
        if (!popover.$element.is(e.target)) {
            popover.inState.click = false;
            popover.hide();                
        }
    });
});
Nik
źródło
2

Próbowałem wielu wcześniejszych odpowiedzi, naprawdę nic dla mnie nie działa, ale to rozwiązanie:

https://getbootstrap.com/docs/3.3/javascript/#dismiss-on-next-click

Zalecają używanie tagu kotwicy, a nie przycisku i dbanie o atrybuty role = "button" + data-trigger = "focus" + tabindex = "0".

Dawny:

<a tabindex="0" class="btn btn-lg btn-danger" role="button" data-toggle="popover" 
data-trigger="focus" title="Dismissible popover" data-content="amazing content">
Dismissible popover</a>
Ahmed El Damasy
źródło
wypróbuj również to odniesienie: stackoverflow.com/questions/20466903/...
Ahmed El Damasy
1

Wymyśliłem to: mój scenariusz zawierał więcej popoverów na tej samej stronie, a ukrywanie ich po prostu czyniło ich niewidocznymi, dlatego klikanie elementów za popoverem nie było możliwe. Chodzi o to, aby oznaczyć konkretny link popover jako „aktywny”, a następnie możesz po prostu „przełączyć” aktywny popover. Spowoduje to całkowite zamknięcie okna 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"
Adi Nistor
źródło
1

Po prostu usuwam inne aktywne programy popover przed wyświetleniem nowego programu popover (bootstrap 3):

$(".my-popover").popover();

$(".my-popover").on('show.bs.popover',function () {
    $('.popover.in').remove();
});              
andrearonsen
źródło
1

testowane z 3.3.6 i drugie kliknięcie jest w porządku

        $('[data-toggle="popover"]').popover()
            .click(function () {
            $(this).popover('toggle');
        });;

        $(document).on('click', function (e) {
            $('[data-toggle="popover"]').each(function () {
                //the 'is' for buttons that trigger popups
                //the 'has' for icons within a button that triggers a popup
                if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
                    $(this).popover('hide');
                }
            });
        });
Sungwook Ji
źródło
0

demo: http://jsfiddle.net/nessajtr/yxpM5/1/

var clickOver = clickOver || {};
clickOver.uniqueId = $.now();

clickOver.ClickOver = function (selector, options) {
    var self = this;

    //default values
    var isVisible, clickedAway = false;

    var callbackMethod = options.content;
var uniqueDiv = document.createElement("div");
var divId = uniqueDiv.id = ++clickOver.uniqueId;
uniqueDiv.innerHTML = options.loadingContent();

options.trigger = 'manual';
options.animation = false;
options.content = uniqueDiv;

self.onClose = function () {
    $("#" + divId).html(options.loadingContent());
    $(selector).popover('hide')
    isVisible = clickedAway = false;
};
self.onCallback = function (result) {
    $("#" + divId).html(result);
};

$(selector).popover(options);

//events
$(selector).bind("click", function (e) {
    $(selector).filter(function (f) {
        return $(selector)[f] != e.target;
    }).popover('hide');

    $(selector).popover("show");
    callbackMethod(self.onCallback);

    isVisible = !(clickedAway = false);
});

$(document).bind("click", function (e) {
    if (isVisible && clickedAway && $(e.target).parents(".popover").length == 0) {
        self.onClose();
        isVisible = clickedAway = false;
    } else clickedAway = true;
});

}

to jest moje rozwiązanie.

Oğuzhan Topçu
źródło
0

Takie podejście zapewnia zamknięcie okna popover przez kliknięcie w dowolnym miejscu na stronie. Kliknięcie innego elementu, który można kliknąć, powoduje ukrycie wszystkich innych okien podręcznych. Animacja: fałsz jest wymagana, w przeciwnym razie otrzymasz komunikat jquery .remove w konsoli.

$('.clickable').popover({
 trigger: 'manual',
 animation: false
 }).click (evt) ->
  $('.clickable').popover('hide')
  evt.stopPropagation()
  $(this).popover('show')

$('html').on 'click', (evt) ->
  $('.clickable').popover('hide')
Arijit Lahiri
źródło
0

Ok, to moja pierwsza próba odpowiedzi na pytanie o przepełnienie stosu, więc tutaj nic nie idzie: P

Wygląda na to, że nie jest całkiem jasne, czy ta funkcja faktycznie działa od razu na najnowszym bootstrapie (cóż, jeśli chcesz pójść na kompromis, gdzie użytkownik może kliknąć. Nie jestem pewien, czy musisz kliknąć „kliknij” najedź myszą per se, ale na iPadzie kliknięcie działa jak przełącznik.

Rezultatem końcowym jest najechanie myszką lub kliknięcie na pulpicie (większość użytkowników najedzie kursorem). Dotknięcie elementu na urządzeniu dotykowym spowoduje jego podniesienie, a ponowne dotknięcie go zdejmie. Oczywiście jest to niewielki kompromis w stosunku do twojego pierwotnego wymagania, ale przynajmniej twój kod jest teraz czystszy :)

$ (". my-popover"). popover ({trigger: 'click hover'});

Ivan Portugal
źródło
0

Biorąc kod Matta Lockyera, wykonałem prosty reset, aby dom nie był objęty elementem ukrywania.

Kod Matt: http://mattlockyer.com/2013/04/08/close-a-twitter-bootstrap-popover-when-clicking-outside/

Fiddle: http://jsfiddle.net/mrsmith/Wd2qS/

    $('body').on('click', function (e) {
    //hide popover from dom to prevent covering elements
    $('.popover').css('display', 'none');
    //bring popover back if trigger element is clicked
    $('[data-toggle="popover"]').each(function () {
        if ($(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
            $('.popover').css('display', 'block');
        }
    });
    //hide popover with .popover method
    $('[data-toggle="popover"]').each(function () {
        //the 'is' for buttons that trigger popups
        //the 'has' for icons within a button that triggers a popup
        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
            $(this).popover('hide');
        }
    });
});
użytkownik14174
źródło
0

Spróbuj tego, ukryje się, klikając na zewnątrz.

$('body').on('click', function (e) {
    $('[data-toggle="popover"]').each(function () {
    //the 'is' for buttons that trigger popups
    //the 'has' for icons within a button that triggers a popup
    if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
    $(this).popover('hide');
    }
    });
});
Rakesh Vadnal
źródło
0

Miałem problemy z rozwiązaniem mattdlockyer, ponieważ dynamicznie konfigurowałem linki popover przy użyciu kodu w następujący sposób:

$('body').popover({
        selector : '[rel="popover"]'
});

Musiałem to tak zmodyfikować. Naprawiono dla mnie wiele problemów:

$('html').on('click', function (e) {
  $('[data-toggle="popover"]').each(function () {
    //the 'is' for buttons that trigger popups
    //the 'has' for icons within a button that triggers a popup
    if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
        $(this).popover('destroy');
    }
  });
});

Pamiętaj, że zniszczenie pozbywa się elementu, więc część selektora jest ważna przy inicjowaniu popoverów.

bryanjj
źródło