Comment fermer un popover Twitter Bootstrap en cliquant à l'extérieur?

289

Pouvons-nous faire en sorte que les popovers soient licenciables de la même manière que les modaux, c'est-à-dire. les faire se fermer lorsque l'utilisateur clique quelque part en dehors d'eux?

Malheureusement, je ne peux pas simplement utiliser du vrai modal au lieu du popover, car modal signifie position: fixe et ce ne serait plus un popover. :(

Ante Vrli
la source
3
Question similaire: stackoverflow.com/q/8947749/1478467
Sherbrow
Essayez ce stackoverflow.com/a/40661543/5823517 . N'implique pas de passer par les parents
Tunn
data-trigger="hover"et data-trigger="focus"sont une alternative intégrée pour fermer le popover, si vous ne souhaitez pas utiliser la bascule. À mon avis, data-trigger="hover"offre la meilleure expérience utilisateur ... il n'est pas nécessaire d'écrire du code .js supplémentaire ...
Hooman Bahreini

Réponses:

461

Mise à jour: une solution légèrement plus robuste: http://jsfiddle.net/mattdlockyer/C5GBU/72/

Pour les boutons contenant uniquement du texte:

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

Pour les boutons contenant des icônes (ce code a un bogue dans Bootstrap 3.3.6, voir le correctif ci-dessous dans cette réponse)

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

Pour les popovers générés par JS, utilisez '[data-original-title]'à la place de'[data-toggle="popover"]'

Avertissement: la solution ci-dessus permet d'ouvrir plusieurs fenêtres pop-up à la fois.

Un popover à la fois s'il vous plaît:

Mise à jour: Bootstrap 3.0.x, voir code ou violon 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');
        }
    });
});

Cela gère la fermeture des fenêtres pop-up déjà ouvertes et non cliquées ou leurs liens n'ont pas été cliqués.


Mise à jour: Bootstrap 3.3.6, voir violon

Résout le problème où après la fermeture, prend 2 clics pour rouvrir

$(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
        }

    });
});

Mise à jour: En utilisant le conditionnel de l'amélioration précédente, cette solution a été réalisée. Résoudre le problème du double clic et de la popover fantôme:

$(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
la source
2
J'attache à $(document)au lieu de $('body')car parfois le bodyne s'étend pas sur toute la page.
jasop
6
Après avoir activé le popover (et l'action de masquage suivante), le popover n'est pas complètement masqué; ce n'est tout simplement pas visible. Le problème est que le contenu sous le popover invisible mais présent ne peut pas être cliqué ou survolé. Un problème se produit sur la dernière version de Chrome, le dernier bootstrap 3 .js (pourrait également être d'autres navigateurs, ne pourrait pas être dérangé pour vérifier car cette solution de contournement devrait être requise de toute façon)
ravb79
6
Au lieu de '[data-toggle="popover"]', qui ne fonctionne pas avec les popovers générés par JavaScript, j'ai utilisé '[data-original-title]'comme sélecteur.
Nathan
4
Est-ce que quelqu'un sait pourquoi cette solution ne fonctionne pas avec la dernière version de bootstrap? Les événements suivants se produisent: Cliquez sur le bouton pour afficher le popover, puis sur le corps pour ignorer le popover, puis sur le bouton pour afficher le popover et le popover ne s'affiche pas. Après avoir échoué une fois si vous cliquez à nouveau dessus, il s'affiche. C'est très étrange.
JTunney
3
@JTunney J'exécute BS 3.3.6 et je vois toujours ce comportement où il faut deux clics pour ouvrir un popoever après en avoir rejeté un.
sersun
65
$('html').on('mouseup', function(e) {
    if(!$(e.target).closest('.popover').length) {
        $('.popover').each(function(){
            $(this.previousSibling).popover('hide');
        });
    }
});

Cela ferme tous les popovers si vous cliquez n'importe où sauf sur un popover

MISE À JOUR pour 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");
        });
    }
});
user28490
la source
J'ai ajouté une classe au bouton qui déclenche le popover (pop-btn) afin qu'il ne soit pas inclus ... if (! $ (E.target) .closest ('. Popover'). Length &&! $ (E. target) .closest ('. btn'). hasClass ('pop-btn'))
mozgras
2
avec 3 boutons popover, ce code pose problème. dans certains cas, je ne peux pas cliquer sur le bouton et les boutons clignotent.
OpenCode
1
Impossible de faire fonctionner ce code ... vérifiez ce violon et veuillez ajouter un violon à votre réponse. jsfiddle.net/C5GBU/102
mattdlockyer
Parfait pour moi. D'autres réponses ont eu des effets secondaires lorsque mon "clic extérieur" a ouvert un nouveau popover.
Facio Ratio
Cela fonctionne très bien, mais doit avoir un moyen de l'adapter afin que si vous cliquez sur le contenu du popover, il ne se ferme pas. par exemple, si vous cliquez sur du texte à l'intérieur d'une balise <b> à l'intérieur du popover ...
Ben in CA
40

La version la plus simple, la plus sûre , fonctionne avec n'importe quelle version d'amorçage.

Démo: http://jsfiddle.net/guya/24mmM/

Démo 2: Ne pas ignorer en cliquant à l'intérieur du contenu popover http://jsfiddle.net/guya/fjZja/

Démo 3: plusieurs popovers: http://jsfiddle.net/guya/6YCjW/


Le simple fait d'appeler cette ligne supprimera tous les popovers:

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

Ignorez tous les popovers lorsque vous cliquez à l'extérieur avec ce code:

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

L'extrait ci-dessus attache un événement de clic sur le corps. Lorsque l'utilisateur clique sur un popover, il se comportera normalement. Lorsque l'utilisateur clique sur quelque chose qui n'est pas un popover, il ferme tous les popovers.

Cela fonctionnera également avec les popovers initiés avec Javascript, par opposition à d'autres exemples qui ne fonctionneront pas. (voir la démo)

Si vous ne voulez pas ignorer lorsque vous cliquez à l'intérieur du contenu du popover, utilisez ce code (voir le lien vers la 2e démo):

$('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
la source
3
Eu un problème similaire et cela a fonctionné dans Bootstrap 3.
wsams
Si vous rapprochez les popovers de telle sorte qu'ils se chevauchent, lorsque vous masquez un popover en cliquant quelque part à l'extérieur, l'un des liens cesse de fonctionner. Vérifier: jsfiddle.net/qjcuyksb/1
Sandeep Giri
1
La dernière version ne fonctionne pas lors de l'utilisation de bootstrap-datepicker dans le popover.
dbinott
1
J'ai préféré cette solution, car la réponse acceptée a commencé à être un peu un porc de ressources avec une trentaine de fenêtres contextuelles
David G
1
Ce !$(e.target).closest('.popover.in').lengthserait peut -être plus efficace que !$(e.target).parents().is('.popover.in').
joeytwiddle
19

Avec bootstrap 2.3.2, vous pouvez définir le déclencheur sur «focus» et cela fonctionne simplement:

$('#el').popover({trigger:'focus'});
periklis
la source
1
+1, mais note latérale importante: cela ne ferme pas le popover, si vous cliquez à nouveau sur le bouton ou l'ancre, alors que la réponse acceptée le fait.
Christian Gollhardt
18

Ce n'est fondamentalement pas très complexe, mais il y a quelques vérifications à faire pour éviter les problèmes.

Démo (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
la source
2
cela rejette le modal en cliquant partout, pas à l'extérieur
hienbt88
Est-il possible de le faire avec un popover()clic plutôt que de survoler?
Zaki Aziz
3
Bien sûr, mais vous devez appeler stopPropagation()l'événement transmis au gestionnaire de clics (sinon, le gestionnaire masquant masque immédiatement le popover). Démo (jsfiddle)
Sherbrow
J'ai la même fonctionnalité ci-dessous dans beaucoup moins de code. Cette réponse est gonflée et un peu ridicule pour la question ... Tout ce qu'il veut, c'est fermer les popovers lorsque vous cliquez à l'extérieur ... C'est exagéré et laid!
mattdlockyer
2
Correction, je crois que j'ai de MEILLEURES fonctionnalités en FAR moins de code. Il suppose que vous ne voulez qu'une seule fenêtre contextuelle à la fois pour être visible. Si vous aimez cela, veuillez voter pour ma réponse ci-dessous: réponse jsfiddle.net/P3qRK/1 : stackoverflow.com/a/14857326/1060487
mattdlockyer
16

Aucune des supposées solutions à vote élevé n'a fonctionné correctement pour moi. Chacun mène à un bug lorsque, après avoir ouvert et fermé (en cliquant sur d'autres éléments) le popover pour la première fois, il ne s'ouvre plus, jusqu'à ce que vous fassiez deux clics sur le lien de déclenchement au lieu d'un.

Je l'ai donc légèrement modifié:

$(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 Sergeyev
la source
1
Sympa, ça marche pour moi. BTW vous avez oublié a); à la fin de votre code après la dernière}
Merlin
1
Eu le même problème lié au deuxième clic. Cela devrait être la réponse à toute épreuve!
Felipe Leão
J'ai également essayé les solutions précédentes ci-dessus, mais comme guide pour ceux qui recherchent également une solution à partir de 2016, c'est une meilleure solution.
dariru
meilleure réponse, fonctionne comme annoncé. comme indiqué, d'autres non. cela devrait être la meilleure réponse
duggi
Fonctionne parfaitement sauf que je n'ai pas utilisé data-toggel = "popover". Mais vous pouvez spécifier n'importe quel sélecteur qui correspond à vos éléments de déclenchement popover. Belle solution et la seule qui a résolu le problème des deux clics pour moi.
shock_gone_wild
11

J'ai fait un jsfiddle pour vous montrer comment faire:

http://jsfiddle.net/3yHTH/

L'idée est d'afficher le popover lorsque vous cliquez sur le bouton et de masquer le popover lorsque vous cliquez en dehors du bouton.

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
la source
belle démo. Je me demande comment vous pourriez appeler popover sur l'objet Jquery, popover est un plugin bootstrap js, mais vous n'y incluez aucun fichier bootstrap js?
bingjie2680
Il y a un fichier js dans le jsfiddle. Regardez la colonne de gauche -> Gérer les ressources.
Pigueiras
Ok, je vois qu'il y a un bootstrap js. mais ce n'est pas vérifié, ça marche toujours?
bingjie2680
Oui cela fonctionne. Quoi qu'il en soit, j'ai cherché dans google: jsfiddle bootstrapet cela m'a donné le squelette de bootstrap css + js dans jsfiddle.
Pigueiras
2
Mon seul problème avec ceci est que vous masquez le popover lorsque vous cliquez dessus. Autant utiliser une info-bulle.
NoBrainer
7

ajoutez simplement cet attribut avec l'élément

data-trigger="focus"
siraj k
la source
Initialement, cela n'a pas fonctionné pour moi avec Bootstrap 3.3.7, mais j'ai lu les documents et ils contiennent des conseils qui méritent d'être mentionnés ici. À partir de l'exemple popover Dismissible dans la documentation "Pour un comportement approprié entre les navigateurs et les plates-formes, vous devez utiliser la balise <a>, pas la balise <button>, et vous devez également inclure les attributs role =" button "et tabindex . "
Jeff
3

Cela a déjà été demandé ici . La même réponse que j'ai donnée alors s'applique toujours:

J'avais un besoin similaire et j'ai trouvé cette super petite extension du Twitter Bootstrap Popover de Lee Carmichael, appelée BootstrapX - clickover . Il a également quelques exemples d'utilisation ici . Fondamentalement, cela transformera le popover en un composant interactif qui se fermera lorsque vous cliquez ailleurs sur la page ou sur un bouton de fermeture dans le popover. Cela permettra également d'ouvrir plusieurs popovers à la fois et un tas d'autres fonctionnalités intéressantes.

Miika L.
la source
3

Il est tard pour la fête ... mais je pensais le partager. J'adore le popover mais il a si peu de fonctionnalités intégrées. J'ai écrit une extension bootstrap .bubble () qui est tout ce que j'aimerais que Popover soit. Quatre façons de rejeter. Cliquez à l'extérieur, basculez sur le lien, cliquez sur le X et appuyez sur échapper.

Il se positionne automatiquement pour ne jamais quitter la page.

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

Ce n'est pas une auto promo gratuite ... J'ai saisi le code des autres tellement de fois dans ma vie, j'ai voulu offrir mes propres efforts. Donnez-lui un tourbillon et voyez si cela fonctionne pour vous.

Itumac
la source
3

Selon http://getbootstrap.com/javascript/#popovers ,

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

Utilisez le déclencheur de focus pour fermer les fenêtres pop-up au prochain clic de l'utilisateur.

$('.popover-dismiss').popover({
    trigger: 'focus'
})
effe
la source
2
Ne fonctionne pas sur les navigateurs Mac qui suivent le comportement natif d'OS X (qui ne fait ni focus ni flou sur les boutons au clic). Il s'agit notamment de Firefox et Safari. Les gars de Bootstrap ont fait une grosse erreur ici, car ces popovers ne peuvent même pas être ouverts, et encore moins rejetés.
Ante Vrli
2
@AnteVrli Peut-être que ce n'était pas encore dans la documentation quand vous avez écrit votre commentaire mais maintenant les docs disent: "Pour un bon comportement entre les navigateurs et les plateformes, vous devez utiliser la <a>balise, pas la <button>balise, et vous devez également inclure le role="button"et tabindexles attributs." L'avez-vous essayé avec ces spécifications?
Louis
3
Eh bien, il y a un problème avec cette réponse, qui n'a rien à voir avec la compatibilité de la plate-forme: appuyer sur un bouton de la souris à l' intérieur d' un popover fera disparaître le popover car l'élément qui déclenche le popover perdra le focus. Oubliez que les utilisateurs puissent copier-coller à partir des fenêtres contextuelles: dès que le bouton de la souris est enfoncé, la fenêtre contextuelle se ferme. Si vous avez des éléments actionnables dans le popover (boutons, liens), les utilisateurs ne pourront pas les utiliser.
Louis
Voilà pour «multiplateforme» parce que dans le bootstrap 4.0.0-beta et 4.0.0-beta.2, je ne peux pas faire fonctionner cela sur Mac dans Chrome :(
rmcsharry
3

Solution acceptée modifiée. Ce que j'ai vécu, c'est qu'après que certains popovers aient été cachés, il faudrait les cliquer deux fois pour réapparaître. Voici ce que j'ai fait pour m'assurer que le popover ('hide') n'était pas appelé sur les popovers déjà cachés.

$('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
la source
3

Cette solution fonctionne très bien:

$("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
la source
2
jQuery("#menu").click(function(){ return false; });
jQuery(document).one("click", function() { jQuery("#menu").fadeOut(); });
hienbt88
la source
2

Vous pouvez également utiliser le bullage d'événements pour supprimer la fenêtre contextuelle du DOM. C'est un peu sale, mais ça marche bien.

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

Dans votre html, ajoutez la classe .popover-close au contenu à l'intérieur du popover qui devrait fermer le popover.

Hendrik
la source
2

Il semble que la méthode 'hide' ne fonctionne pas si vous créez le popover avec délégation de sélecteur, à la place 'destroy' doit être utilisé.

Je l'ai fait fonctionner comme ça:

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

Vladimir Dimchev
la source
2

Nous avons découvert que nous avions un problème avec la solution de @mattdlockyer (merci pour la solution!). Lorsque vous utilisez la propriété selector pour le constructeur popover comme ceci ...

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

... la solution proposée pour BS3 ne fonctionnera pas. Au lieu de cela, il crée une seconde instance popover locale à son $(this). Voici notre solution pour éviter cela:

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

Comme mentionné, le $(this).popover('hide');créera une deuxième instance en raison de l'auditeur délégué. La solution fournie ne cache que les popovers déjà instanciés.

J'espère que je pourrais vous faire gagner du temps.

noyau
la source
2

Bootstrap prend nativement en charge ceci :

JS Bin Demo

Marquage spécifique requis pour le rejet au prochain clic

Pour un comportement approprié entre les navigateurs et les plates-formes, vous devez utiliser la <a>balise, pas la <button>balise, et vous devez également inclure les attributs role="button"et tabindex.

Tanner Perrien
la source
Dans bootstrap 4.0.0-beta et 4.0.0-beta.2, je ne peux pas faire fonctionner cela sur Mac dans Chrome :(
rmcsharry
En cliquant n'importe où, vous fermez ce popover, le questionneur exige que "cliquer en dehors du popover le ferme", ce qui est différent.
philw
2

cette solution se débarrasse du 2ème clic embêtant lors de la deuxième apparition du popover

testé avec 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
la source
2

J'ai essayé plusieurs des réponses précédentes, vraiment rien ne fonctionne pour moi mais cette solution a fait:

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

Ils recommandent d'utiliser la balise d'ancrage et non le bouton et de prendre soin des attributs role = "button" + data-trigger = "focus" + tabindex = "0".

Ex:

<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
la source
essayez aussi cette référence: stackoverflow.com/questions/20466903/…
Ahmed El Damasy
1

Je suis venu avec ceci: Mon scénario incluait plus de popovers sur la même page, et les cacher les rendait simplement invisibles et à cause de cela, cliquer sur les éléments derrière le popover n'était pas possible. L'idée est de marquer le lien popover spécifique comme «actif», puis vous pouvez simplement «basculer» le popover actif. Cela fermera complètement le 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
la source
1

Je supprime simplement les autres popovers actifs avant que le nouveau popover ne s'affiche (bootstrap 3):

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

$(".my-popover").on('show.bs.popover',function () {
    $('.popover.in').remove();
});              
andrearonsen
la source
1

testé avec 3.3.6 et le deuxième clic est ok

        $('[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
la source
0

démo: 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;
});

}

c'est ma solution.

Oğuzhan Topçu
la source
0

Cette approche garantit que vous pouvez fermer un popover en cliquant n'importe où sur la page. Si vous cliquez sur une autre entité cliquable, elle masque tous les autres popovers. L'animation: false est requise sinon vous obtiendrez une erreur jquery .remove dans votre console.

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

Ok, c'est ma première tentative de répondre à quelque chose sur stackoverflow alors ça ne va rien: P

Il semble qu'il ne soit pas tout à fait clair que cette fonctionnalité fonctionne réellement hors de la boîte sur le dernier bootstrap (eh bien, si vous êtes prêt à faire un compromis l'utilisateur peut cliquer. Je ne suis pas sûr si vous devez mettre "cliquez sur" survoler en soi, mais sur un iPad, cliquez sur fonctionne comme une bascule.

Le résultat final est, sur un bureau, vous pouvez survoler ou cliquer (la plupart des utilisateurs survolent). Sur un appareil tactile, toucher l'élément le fera monter et le toucher à nouveau le fera descendre. Bien sûr, c'est un léger compromis par rapport à votre exigence d'origine mais au moins votre code est maintenant plus propre :)

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

Ivan Portugal
la source
0

En prenant le code de Matt Lockyer, j'ai fait une simple réinitialisation pour que le dom ne soit pas couvert par l'élément sur hide.

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

Violon: 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');
        }
    });
});
user14174
la source
0

Essayez ceci, cela se cachera en cliquant à l'extérieur.

$('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
la source
0

J'avais des problèmes avec la solution de mattdlockyer parce que je configurais dynamiquement des liens popover en utilisant du code comme celui-ci:

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

J'ai donc dû le modifier comme ça. Cela a résolu beaucoup de problèmes pour moi:

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

N'oubliez pas que destroy supprime l'élément, donc la partie sélecteur est importante lors de l'initialisation des popovers.

bryanjj
la source