Wie kann ich ein Twitter Bootstrap-Popover mit einem Klick von einer beliebigen Stelle auf der Seite schließen?


154

Ich verwende derzeit Popover mit Twitter Bootstrap, die wie folgt initiiert wurden:

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

Wie Sie sehen können, werden sie manuell ausgelöst, und durch Klicken auf .popup-marker (ein Div mit einem Hintergrundbild) wird ein Popover umgeschaltet. Das funktioniert gut, aber ich möchte das Popover auch mit einem Klick an einer anderen Stelle auf der Seite schließen können (aber nicht auf dem Popover selbst!).

Ich habe ein paar verschiedene Dinge ausprobiert, darunter die folgenden, aber keine Ergebnisse zu zeigen:

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

Wie kann ich das Popover mit einem Klick an einer anderen Stelle auf der Seite schließen, jedoch nicht mit einem Klick auf das Popover selbst?


Hm, ich würde denken, das würde funktionieren ... hast du zufällig einen Link dazu online?
Thatryan

Antworten:


102

Unter der Annahme, dass immer nur ein Popover sichtbar sein kann, können Sie mithilfe einer Reihe von Flags markieren, wann ein Popover sichtbar ist, und diese erst dann ausblenden.

Wenn Sie den Ereignis-Listener im Dokumentkörper festlegen, wird er ausgelöst, wenn Sie auf das mit 'Popup-Marker' gekennzeichnete Element klicken. Also musst du anrufenstopPropagation() das Ereignisobjekt . Wenden Sie denselben Trick an, wenn Sie auf das Popover selbst klicken.

Unten finden Sie einen funktionierenden JavaScript-Code, der dies tut. Es verwendet 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/

Die einzige Einschränkung ist, dass Sie nicht 2 Popover gleichzeitig öffnen können. Aber ich denke, das wäre für den Benutzer trotzdem verwirrend :-)


1
Wenn Sie in dieser jsfiddle auf das Popover selbst klicken, wird das Popover ausgeblendet - nicht ganz das, was tnorthcutt verlangt hat.
Jonathon Hill

1
@ RaduCugut das ist eine großartige Lösung. Aber es hat einen Fehler. Klicken Sie einmal auf zzzzz und das Popover wird angezeigt. Klicken Sie nun einmal auf den weißen Hintergrund. Das Popup verschwindet. Klicken Sie nun erneut auf den weißen Hintergrund. Und jetzt klicke erneut auf zzzz und es funktioniert nicht. : - |
Houman

1
@Kave du hast recht, ich habe die Geige und die Antwort geändert, um dies zu korrigieren. jsfiddle.net/AFffL/177
Radu Cugut

3
Warum nicht einfach $ ('. Popup-marker'). Popover ('hide') (um sie alle auszublenden) vor $ (this) .popover ('show') ausführen, wodurch keine isVisible- und clickedAway-Variablen mehr erforderlich sind?
Nathan Hangen

1
Diese Lösung gab mir einige Probleme (durch Klicken auf das Element '.popup-marker' des geöffneten Popovers funktionierten die Popover danach nicht mehr). Ich habe mir eine weitere Lösung ausgedacht (siehe unten), die für mich funktioniert und einfacher zu sein scheint (ich verwende Bootstrap 2.3.1).
RayOnAir

76

Das ist noch einfacher:

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

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

Einverstanden. Und zumindest für mich ist das der richtige Weg. Die erste Option scheint eine "schnelle Lösung" zu sein.
Denis Lins

4
Wollte dies nutzen, hat aber aus irgendeinem Grund nicht geklappt. Die Klickereignisse wurden nie erreicht, htmlweil e.stopPropagation();ich stattdessen etwas verwendet habe, $('.popup-marker').on('show', function(event) { $('.popup-marker').filter(function(index, element) { return element != event.target; }).popover('hide'); });das den Job auch gut gemacht hat (ich weiß nicht, ob es einen Leistungsunterschied gibt)
Cornelis

1
Dies ist die beste Antwort IMO.
Loolooii

1
Die Zusammenstellung der Antworten von @pbaron und @Cornelis funktioniert am besten. Was ich hinzugefügt habe, ist Cornelis-Code in der zweiten "Klick" -Funktion (kurz vor dem $(this).popover('toggle');Teil. Wenn Sie dann mehrere "Popup-Marker" -Objekte haben, werden durch Klicken auf jedes die anderen geschlossen.
Alekwisnia

2
Das einzige Problem dabei ist, dass das Popover immer noch da ist, nur versteckt. Wenn Sie beispielsweise Links im Popover haben, können Sie den Cursor an die Stelle bewegen, an der er sich befand, und trotzdem den Cursor über diese Links ändern.
Gletscher

48

Ich hatte ein ähnliches Bedürfnis und fand diese tolle kleine Erweiterung des Twitter Bootstrap Popover von Lee Carmichael namens BootstrapX - Clickover . Er hat hier auch einige Anwendungsbeispiele . Grundsätzlich wird das Popover in eine interaktive Komponente umgewandelt, die geschlossen wird, wenn Sie auf eine andere Stelle auf der Seite oder auf eine Schaltfläche zum Schließen innerhalb des Popovers klicken. Dies ermöglicht auch das gleichzeitige Öffnen mehrerer Popover und eine Reihe weiterer nützlicher Funktionen.

Plugin finden Sie hier .

Anwendungsbeispiel

<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
Das ist wirklich toll. Super einfach.
Doug

Exzellentes Plugin! Danke für den Link.
Matt Wilson

1
Ich habe es gerade ausprobiert und es funktioniert großartig. War so einfach wie das Ändern der Relation eines vorhandenen Popovers von "Popover" in "Clickover".
Dmase05

Laufen auf Bootstrap v2.3.1, keine Probleme.
Kevin Dewalt

37

Die akzeptierte Lösung gab mir einige Probleme (durch Klicken auf das Element '.popup-marker' des geöffneten Popovers funktionierten die Popover danach nicht mehr). Ich habe mir diese andere Lösung ausgedacht, die perfekt für mich funktioniert und recht einfach ist (ich verwende 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');
    }
});

UPDATE: Dieser Code funktioniert auch mit Bootstrap 3!


1
Dies ist eine großartige Lösung. Danke dir.
Gavin

1
Gute Lösung. Warum benutzt du das nicht so, if (!$(e.target).is('.popup-marker') && !$(e.target).parents('.popover').length > 0)dass das Popup nicht geschlossen wird, selbst wenn es HTML-Inhalt hat
ykay sagt Reinstate Monica

2
Oder besserif (!$(e.target).is('.popup-marker') && $(e.target).closest('.popover').length === 0)
Fabdouglas

19

Lesen Sie hier "Beim nächsten Klick schließen" http://getbootstrap.com/javascript/#popovers

Sie können den Fokus-Trigger verwenden, um Popover beim nächsten Klick zu schließen. Sie müssen jedoch das <a>Tag verwenden, nicht das <button>Tag, und Sie müssen auch ein tabindexAttribut einfügen ...

Beispiel:

<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
Die Frage besagte, dass er nicht wollte, dass es geschlossen wird, wenn der Klick auf das Popover war. Dies schließt es bei jedem Klick irgendwo ab.
Fred

1
Das Hinzufügen von data-trigger = "focus" hat den Start meiner Popover gestoppt, bis ich diesen Beitrag gelesen und das tabindex-Attribut hinzugefügt habe. Jetzt gehts!
PixelGraph

2
Zur Information funktioniert dies auch tooltip, auch wenn es im eigentlichen Dokument nicht eindeutig erwähnt ist.
AlexB

7

Alle vorhandenen Antworten sind ziemlich schwach, da sie darauf beruhen, alle Dokumentereignisse zu erfassen, dann aktive Popovers zu finden oder den Aufruf von zu ändern .popover().

Ein viel besserer Ansatz besteht darin, auf show.bs.popoverEreignisse im Hauptteil des Dokuments zu achten und dann entsprechend zu reagieren. Unten finden Sie Code, der Popovers schließt, wenn auf das Dokument geklickt oder escgedrückt wird, und nur Ereignis-Listener bindet, wenn Popover angezeigt werden:

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 Dies ist die sauberste und erweiterbarste Lösung. Wenn Sie auch ein Framework wie das Backbone verwenden, geben Sie dies einfach in Ihren Initialisierungscode ein und es kümmert sich um die Behandlung der Popovers.
JohnP

Diese Antwort fügt auch Leistungsprobleme hinzu und ermöglicht die Behandlung von komplexerem HTML innerhalb des Popovers.
Ricardo

Tolle Lösung; war in der Lage, es in eine Reaktionsmethode ziemlich leicht fallen zu lassen. Ein Vorschlag: $(event.target).data("bs.popover").inState.click = false;Fügen Sie die Funktion onPopoverHide hinzu, damit Sie nicht zweimal klicken müssen, um nach dem Schließen erneut zu öffnen.
sco_tt

Neugierig, ob Sie mit zwei Popups eine Geige daraus machen könnten. Als ich Ihren Code in meiner Anwendung implementierte, konnte ich auf Popup klicken, um Popup zu öffnen, und mehrere wurden angezeigt. Durch Klicken auf den 'Körper' wurde nur der zuletzt angezeigte entfernt.
Terry


2

Aus irgendeinem Grund hat keine der anderen Lösungen hier für mich funktioniert. Nach vielen Fehlerbehebungen bin ich jedoch endlich zu dieser Methode gekommen, die perfekt funktioniert (zumindest für mich).

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

In meinem Fall habe ich einer Tabelle ein Popover hinzugefügt und es absolut über / unter dem tdangeklickten positioniert . Die Tabellenauswahl wurde von jQuery-UI Selectable übernommen, daher bin ich mir nicht sicher, ob dies störend war. Wenn ich jedoch in das Popover klickte, funktionierte mein gezielter Klick-Handler $('.popover')nie und die Ereignisbehandlung wurde immer an das delegiert$(html) Click-Handler . Ich bin ziemlich neu bei JS, also vermisse ich vielleicht nur etwas?

Wie auch immer, ich hoffe das hilft jemandem!


Übrigens bin ich mir nicht sicher, ob es wichtig ist, aber ich habe diese Methode für Bootstrap 2 verwendet. Ich gehe davon aus, dass sie für Bootstrap 3 funktioniert, habe sie aber nicht bestätigt.
Moollaza

2

Ich gebe allen meinen Popover-Ankern die Klasse activate_popover. Ich aktiviere sie alle auf einmal beim Laden

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

Um die Click-Away-Funktion zum Laufen zu bringen, verwende ich (im Kaffeeskript):

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

Was mit Bootstrap 2.3.1 einwandfrei funktioniert


Dies funktionierte für mich, außer dass ich .prev()in der ersten ifKlausel loswerden musste . Ich verwende Bootstrap 3.2.0.2. Vielleicht gibt es einen Unterschied? Sie können auch einfach die gesamte zweite ifKlausel weglassen, wenn Sie möchten, dass mehrere Popups gleichzeitig geöffnet sind. Klicken Sie einfach auf eine beliebige Stelle, die kein Popover-aktivierendes Element ist (in diesem Beispiel die Klasse 'Popover aktivieren'), um alle geöffneten Popover zu schließen. Funktioniert super!
Andrew Swihart

2

Obwohl es hier viele Lösungen gibt, möchte ich auch meine vorschlagen. Ich weiß nicht, ob es dort oben eine Lösung gibt, die alles löst, aber ich habe 3 davon ausprobiert und sie hatten Probleme, wie das Klicken Auf dem Popover wird es selbst ausgeblendet, andere, die, wenn ich auf andere Popover-Schaltflächen geklickt hätte, beide / mehrere Popover immer noch angezeigt würden (wie in der ausgewählten Lösung). Wie auch immer, dieser hat alles behoben

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

Ich würde den Fokus auf das neu erstellte Popup setzen und es bei Unschärfe entfernen. Auf diese Weise muss nicht überprüft werden, auf welches Element des DOM geklickt wurde, und das Popup kann angeklickt und auch ausgewählt werden: Es verliert nicht den Fokus und verschwindet nicht.

Der Code:

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

Hier ist die Lösung, die für mich sehr gut funktioniert hat, wenn sie helfen kann:

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

Hier ist meine Lösung für das, was es wert ist:

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

Ich hatte ein Problem damit, dass es auf Bootstrap 2.3.2 funktioniert. Aber ich habe es so geschoben:

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

1

@David Wolever-Lösung leicht optimiert:

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

Diese Frage wurde auch hier gestellt und meine Antwort bietet nicht nur eine Möglichkeit, die jQuery DOM-Traversal-Methoden zu verstehen, sondern auch zwei Optionen zum Behandeln des Schließens von Popovers durch Klicken nach außen.

Öffnen Sie mehrere Popover gleichzeitig oder jeweils ein Popover.

Außerdem können diese kleinen Codefragmente das Schließen von Schaltflächen mit Symbolen übernehmen!

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


1

Dieser funktioniert wie ein Zauber und ich benutze ihn.

Es öffnet das Popover, wenn Sie klicken, und wenn Sie erneut klicken, wird es geschlossen. Auch wenn Sie außerhalb des Popovers klicken, wird das Popover geschlossen.

Dies funktioniert auch mit mehr als 1 Popover.

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

Dies ist der einzige, der für mich gearbeitet hat. Bootstrap 3.20. Danke.
Telegard

1

Eine andere Lösung, die das Problem abdeckte, das ich beim Klicken auf Nachkommen des Popovers hatte:

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

Ich mache es wie unten

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

Hoffe das hilft!


0

Wenn Sie versuchen, Twitter Bootstrap Popover mit pjax zu verwenden, hat dies für mich funktioniert:

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

0

@ RayOnAir, ich habe das gleiche Problem mit früheren Lösungen. Ich komme auch der @ RayOnAir-Lösung nahe. Eine Sache, die verbessert wurde, ist das Schließen eines bereits geöffneten Popovers, wenn Sie auf einen anderen Popover-Marker klicken. Mein Code lautet also:

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

0

Ich fand, dass dies eine modifizierte Lösung des obigen Vorschlags von pbaron ist, da seine Lösung das Popover ('hide') für alle Elemente mit der Klasse 'popup-marker' aktiviert hat. Wenn Sie jedoch popover () für HTML-Inhalte anstelle von Dateninhalten verwenden, wie unten beschrieben, aktivieren alle Klicks in diesem HTML-Popup tatsächlich das Popover ('hide'), wodurch das Fenster sofort geschlossen wird. Diese Methode unten durchläuft jedes .popup-marker-Element und ermittelt zuerst, ob das übergeordnete Element mit der angeklickten .popup-marker-ID zusammenhängt, und wenn ja, wird es nicht ausgeblendet. Alle anderen Divs sind versteckt ...

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

Ich habe mir das ausgedacht:

Mein Szenario enthielt mehr Popover auf derselben Seite, und das Ausblenden machte sie nur unsichtbar. Aus diesem Grund war es nicht möglich, auf Elemente hinter dem Popover zu klicken. Die Idee ist, den spezifischen Popover-Link als "aktiv" zu markieren und dann können Sie den aktiven Popover einfach "umschalten". Dadurch wird das Popover vollständig geschlossen.

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

Ich habe versucht, eine einfache Lösung für ein einfaches Problem zu finden. Die obigen Beiträge sind gut, aber für ein einfaches Problem so kompliziert. Also habe ich eine einfache Sache gemacht. Ich habe gerade eine Schaltfläche zum Schließen hinzugefügt. Es ist perfekt für mich.

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

Ich mag das, einfach und doch effektiv.

var openPopup;

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

    }
    openPopup=this;
});

0

Fügen Sie btn-popoverIhrer Popover-Schaltfläche / Ihrem Popover-Link eine Klasse hinzu, die das Popover öffnet. Dieser Code schließt die Popover, wenn Sie außerhalb klicken.

$('body').on('click', function(event) {
  if (!$(event.target).closest('.btn-popover, .popover').length) {
    $('.popover').popover('hide');
  }
});

0

Eine noch einfachere Lösung: Durchlaufen Sie einfach alle Popover und verstecken Sie sie, wenn nicht 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');
        }
    });
});

0
$('.popForm').popover();

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

Um klar zu sein, lösen Sie einfach das Popover aus


0

Dies sollte in Bootstrap 4 funktionieren:

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

Erläuterung:

  • Im ersten Abschnitt wird das Popover gemäß den folgenden Dokumenten angezeigt: https://getbootstrap.com/docs/4.0/components/popovers/
  • Das erste "if" im zweiten Abschnitt prüft, ob das angeklickte Element ein Nachkomme von # my-popover-trigger ist. Wenn dies zutrifft, wird das Popover umgeschaltet (es behandelt das Klicken auf den Auslöser).
  • Das zweite "if" im zweiten Abschnitt prüft, ob das angeklickte Element ein Nachkomme der Popover-Inhaltsklasse ist, die in der Init-Vorlage definiert wurde. Ist dies nicht der Fall, bedeutet dies, dass sich der Klick nicht im Popover-Inhalt befand und das Popover ausgeblendet werden kann.

Könnten Sie bitte Ihren Code näher erläutern? Fügen Sie eine Erklärung zu dem hinzu, was Sie tun?
Tod Waltz

@DeathWaltz Ich habe gerade eine Erklärung in die Antwort eingefügt.
Bart Blast

-1

Versuchen Sie data-trigger="focus"statt "click".

Dies löste das Problem für mich.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.