it-swarm.com.de

Wie kann ich Bootstrap-Popover am Leben erhalten, während der Popover im Schwebeflug ist?

Ich verwende das Popover von Twitter boostrap, um eine Hover-Karte zu erstellen, um Benutzerinformationen anzuzeigen, und ich stoße Popover auf die Mouseover-Prüfung - jsfiddle here aus. Ich möchte diesen Popover am Leben erhalten, während er schwebt.

<a href="#" id="example" class="btn btn-danger" rel="popover" >hover for popover</a>

$('#example').popover({
        html : true,
        trigger : 'manual',
        content : function() {
            return '<div class="box"></div>';
        }
    });
$(document).on('mouseover', '#example', function(){
    $('#example').popover('show');
});
$(document).on('mouseleave', '#example', function(){
    $('#example').popover('hide');
});

Sie können an die Facebook-Hover-Karte denken. Ich möchte es genauso machen. Wie kann ich das machen?

93
vikas devde

Ich bin nach einer anderen Lösung dafür gekommen ... hier ist der Code

    $('.selector').popover({
        html: true,
        trigger: 'manual',
        container: $(this).attr('id'),
        placement: 'top',
        content: function () {
            $return = '<div class="hover-hovercard"></div>';
        }
    }).on("mouseenter", function () {
        var _this = this;
        $(this).popover("show");
        $(this).siblings(".popover").on("mouseleave", function () {
            $(_this).popover('hide');
        });
    }).on("mouseleave", function () {
        var _this = this;
        setTimeout(function () {
            if (!$(".popover:hover").length) {
                $(_this).popover("hide")
            }
        }, 100);
    });
76
vikas devde

Diesen Arbeitscode in Plunker anzeigen

Kleine Modifikation (von der von vikas bereitgestellten Lösung) für meinen Anwendungsfall. 
1. Popover bei Hover-Ereignis für die Popover-Schaltfläche öffnen
2. Halten Sie das Popover-Fenster geöffnet, wenn Sie sich über dem Popover-Feld befinden
3. Schließen Sie das Popover auf Mauszeiger für entweder den Popover-Button oder das Popover-Feld.

$('.pop').popover({
    trigger: 'manual',
    html: true,
    animation: false
})
.on('mouseenter', function () {
    var _this = this;
    $(this).popover('show');
    $('.popover').on('mouseleave', function () {
        $(_this).popover('hide');
    });
}).on('mouseleave', function () {
    var _this = this;
    setTimeout(function () {
        if (!$('.popover:hover').length) {
            $(_this).popover('hide');
        }
    }, 300);
});

Spiel damit im Plunker

142
OkezieE

Hier ist mein Take: http://jsfiddle.net/WojtekKruszewski/Zf3m7/22/

Wenn Sie die Maus vom Popover-Auslöser zum tatsächlichen Popover-Inhalt diagonal bewegen, bewegen Sie den Mauszeiger über die unten stehenden Elemente. Ich wollte mit solchen Situationen umgehen - solange Sie Popover-Inhalte erreichen, bevor das Timeout ausgelöst wird, sind Sie sicher (der Popover wird nicht verschwinden). Es erfordert die Option delay.

Dieser Hack überschreibt grundsätzlich die Popover-Funktion leave, ruft jedoch das Original auf (das den Timer startet, um den Popover auszublenden). Dann wird ein einmaliger Listener an mouseenter Popover-Inhaltselemente angehängt.

Wenn die Maus in das Popover-Fenster kommt, wird der Timer gelöscht. Dann wird beim Popover auf mouseleave zugegriffen und wenn es ausgelöst wird, ruft es die ursprüngliche Verlassen-Funktion auf, damit der Timer ausgeblendet werden kann.

var originalLeave = $.fn.popover.Constructor.prototype.leave;
$.fn.popover.Constructor.prototype.leave = function(obj){
  var self = obj instanceof this.constructor ?
    obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
  var container, timeout;

  originalLeave.call(this, obj);

  if(obj.currentTarget) {
    container = $(obj.currentTarget).siblings('.popover')
    timeout = self.timeout;
    container.one('mouseenter', function(){
      //We entered the actual popover – call off the dogs
      clearTimeout(timeout);
      //Let's monitor popover content instead
      container.one('mouseleave', function(){
        $.fn.popover.Constructor.prototype.leave.call(self, self);
      });
    })
  }
};
28

Ich habe den Triggersatz auf hover gesetzt, den Containersatz dem #element zugewiesen und schließlich eine Platzierung der box zu right hinzugefügt.

Dies sollte dein Setup sein: 

$('#example').popover({
    html: true,
    trigger: 'hover',
    container: '#example',
    placement: 'right',
    content: function () {
        return '<div class="box"></div>';
    }
});

und #example css muss position:relative; überprüfen:

https://jsfiddle.net/9qn6pw4p/1/

Bearbeitet

Diese Geige hat beide Links, die ohne Probleme funktionieren http://jsfiddle.net/davidchase03/FQE57/4/

12
David Chase

Ich denke, ein einfacher Weg wäre dies:

$('.popover').each(function () {
                    var $this = $(this);
                    $this.popover({
                        trigger: 'hover',
                        content: 'Content Here',
                        container: $this
                    })
                });

Auf diese Weise wird das Popover im Zielelement selbst erstellt. Wenn Sie den Mauszeiger über den Popover bewegen, bleibt er jedoch über dem Element. Bootstrap 3.3.2 funktioniert gut damit. Bei älteren Versionen treten möglicherweise Probleme mit der Animation auf. Daher sollten Sie "animation: false" deaktivieren.

8
Cu Lý

So habe ich Bootstrap-Popover mit Hilfe anderer Bits im Netz gemacht. Ruft den Titel und den Inhalt dynamisch von den verschiedenen vor Ort angezeigten Produkten ab. Jedes Produkt oder Popover erhält eine eindeutige ID. Popover wird ausgeblendet, wenn Sie das Produkt ($ this .pop) oder den Popover beenden. Timeout wird verwendet, wenn das Popover bis zum Beenden durch das Produkt anstelle des Popovers angezeigt wird.

$(".pop").each(function () {
        var $pElem = $(this);
        $pElem.popover(
            {
                html: true,
                trigger: "manual",
                title: getPopoverTitle($pElem.attr("id")),
                content: getPopoverContent($pElem.attr("id")),
                container: 'body',
                animation:false
            }
        );
    }).on("mouseenter", function () {
        var _this = this;
        $(this).popover("show");
        console.log("mouse entered");
        $(".popover").on("mouseleave", function () {
            $(_this).popover('hide');
        });
    }).on("mouseleave", function () {
        var _this = this;
        setTimeout(function () {
            if (!$(".popover:hover").length) {
                $(_this).popover("hide");
            }
        }, 100);
    });
    function getPopoverTitle(target) {
        return $("#" + target + "_content > h3.popover-title").html();
    };

    function getPopoverContent(target) {
        return $("#" + target + "_content > div.popover-content").html();
    };
7
hoektoe

Hier ist eine von mir entwickelte Lösung, die anscheinend gut funktioniert und es Ihnen ermöglicht, die normale Bootstrap-Implementierung zum Aktivieren aller Popovers zu verwenden.

Ursprüngliche Geige: https://jsfiddle.net/eXpressive/hfear592/

Portiert auf diese Frage:

<a href="#" id="example" class="btn btn-danger" rel="popover" >hover for popover</a>

$('#example').popover({
    html : true,
    trigger : 'hover',
    content : function() {
        return '<div class="box"></div>';
    }
}).on('hide.bs.popover', function () {
    if ($(".popover:hover").length) {
      return false;
    }                
}); 

$('body').on('mouseleave', '.popover', function(){
    $('.popover').popover('hide');
});
4

Einfach :)

$('[data-toggle="popover"]').popover( { "container":"body", "trigger":"focus", "html":true });
$('[data-toggle="popover"]').mouseenter(function(){
    $(this).trigger('focus');
});
1
edmc73

Ich stimme zu, dass der beste Weg ist, die folgende zu verwenden: David Chase , Cu Ly und andere, dass der einfachste Weg dazu ist, die container: $(this)-Eigenschaft wie folgt zu verwenden:

$(selectorString).each(
  var $this = $(this);
  $this.popover({
    html: true,
    placement: "top",
    container: $this,
    trigger: "hover",
    title: "Popover",
    content: "Hey, you hovered on element"
  });
);

Ich möchte hier darauf hinweisen, dass der Popover in diesem Fall alle Eigenschaften des aktuellen Elements erbt. Wenn Sie dies beispielsweise für ein .btn-Element (Bootstrap) durchführen, , können Sie keinen Text im Popover auswählen. Ich wollte das einfach aufnehmen, da ich einige Zeit damit verbracht habe, meinen Kopf darauf zu schlagen.

1
forumulator

Vikas answer funktioniert perfekt für mich, hier füge ich auch Unterstützung für die Verzögerung hinzu (ein-/ausblenden).

var popover = $('#example');
var options = {
    animation : true,
    html: true,
    trigger: 'manual',
    placement: 'right',
    delay: {show: 500, hide: 100}
};   
popover
    .popover(options)
    .on("mouseenter", function () {

        var t = this;
        var popover = $(this);    
        setTimeout(function () {

            if (popover.is(":hover")) {

                popover.popover("show");
                popover.siblings(".popover").on("mouseleave", function () {
                    $(t).popover('hide');
                });
            }
        }, options.delay.show);
    })
    .on("mouseleave", function () {
        var t = this;
        var popover = $(this);

        setTimeout(function () {
            if (popover.siblings(".popover").length && !popover.siblings(".popover").is(":hover")) {
                $(t).popover("hide")
            }
        }, options.delay.hide);
    });     

Bitte beachten Sie auch, dass ich geändert habe:

if (!$(".popover:hover").length) {

mit:

if (popover.siblings(".popover").length && !popover.siblings(".popover").is(":hover")) {

so dass es sich genau auf das geöffnete Popover bezieht, und nicht auf ein anderes

1
user1993198

Die gewählte Antwort funktioniert schlägt jedoch fehl, wenn das Popover mit der body als Container initialisiert wird.

$('a').popover({ container: 'body' });

Eine Lösung, die auf der gewählten Antwort basiert, ist der folgende Code, der vor der Verwendung des Popovers platziert werden muss.

var originalLeave = $.fn.popover.Constructor.prototype.leave;
$.fn.popover.Constructor.prototype.leave = function(obj) {
    var self = obj instanceof this.constructor ? obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type);
    originalLeave.call(this, obj);

    if (obj.currentTarget) {
        self.$tip.one('mouseenter', function() {
            clearTimeout(self.timeout);
            self.$tip.one('mouseleave', function() {
                $.fn.popover.Constructor.prototype.leave.call(self, self);
            });
        })
    }
};

Die Änderung ist minimal, wenn Sie self.$tip verwenden, anstatt das DOM zu durchlaufen, wobei erwartet wird, dass der Popover immer ein Geschwister des Elements ist.

1
Rubens Mariuzzo

Ich fand, dass mouseleave nicht ausgelöst wird, wenn seltsame Dinge passieren, wenn sich der Fensterfokus plötzlich ändert und der Benutzer dann zum Browser zurückkehrt. In solchen Fällen wird mouseleave nie ausgelöst, bis der Cursor übergeht und das Element wieder verlässt.

Diese Lösung, auf die ich gekommen bin, stützt sich auf mouseenter für das window-Objekt. Sie verschwindet also, wenn die Maus auf der Seite irgendwo anders bewegt wird.

Dies wurde entwickelt, um mit mehreren Elementen auf der Seite zu arbeiten, die sie auslösen (wie in einer Tabelle).

var allMenus = $(".menus");
allMenus.popover({
    html: true,
    trigger: "manual",
    placement: "bottom",
    content: $("#menuContent")[0].outerHTML
}).on("mouseenter", (e) => {
    allMenus.not(e.target).popover("hide");
    $(e.target).popover("show");
    e.stopPropagation();
}).on("shown.bs.popover", () => {
    $(window).on("mouseenter.hidepopover", (e) => {
        if ($(e.target).parents(".popover").length === 0) {
            allMenus.popover("hide");
            $(window).off("mouseenter.hidepopover");
        }
    });
});
0
Gabriel Luci
        $(function() {
            $("[data-toggle = 'popover']").popover({
                placement: 'left',
                html: true,
                trigger: "  focus",
            }).on("mouseenter", function() {
                var _this = this;
                $(this).popover("show");
                $(this).siblings(".popover").on("mouseleave", function() {
                    $(_this).popover('hide');
                });
            }).on("mouseleave", function() {
                var _this = this;
                setTimeout(function() {
                    if (!$(".popover:hover").length) {
                        $(_this).popover("hide")
                    }
                }, 100);
            });
        }); 
0
Dinesh Sarak

Gleiches für Tooltips:

Die folgende Lösung funktioniert für mich, weil sie nicht zu jedem 'Mouseenter' Ereignis-Listener hinzufügt und es möglich ist, wieder auf das Tooltip-Element zu zeigen, wodurch der Tooltip erhalten bleibt.

$ ->

  $('.element').tooltip({
    html: true,
    trigger: 'manual'
  }).
  on 'mouseenter', ->
    clearTimeout window.tooltipTimeout
    $(this).tooltip('show') unless $('.tooltip:visible').length > 0
  .
  on 'mouseleave', ->
    _this = this
    window.tooltipTimeout = setTimeout ->
      $(_this).tooltip('hide')
    , 100

$(document).on 'mouseenter', '.tooltip', ->
  clearTimeout window.tooltipTimeout

$(document).on 'mouseleave', '.tooltip', ->
  trigger = $($(this).siblings('.element')[0])
  window.tooltipTimeout = setTimeout ->
    trigger.tooltip('hide')
  , 100
0
phlppn

Es wird flexible mit hover():

$(".my-popover").hover(
    function() {  // mouse in event
        $this = $(this);
        $this.popover({
            html: true,
            content: "Your content",
            trigger: "manual",
            animation: false
            });
        $this.popover("show");
        $(".popover").on("mouseleave", function() {
            $this.popover("hide");
        });
    },
    function() {  // mouse out event
        setTimeout(function() {
            if (!$(".popover:hover").length) {
                $this.popover("hide");
            }
        }, 100);
    } 
)
0
Grey Li

Diese Lösung hat für mich gut funktioniert:

function enableThumbPopover() {
    var counter;

    $('.thumbcontainer').popover({
        trigger: 'manual',
        animation: false,
        html: true,
        title: function () {
            return $(this).parent().find('.thumbPopover > .title').html();
        },
        content: function () {
            return $(this).parent().find('.thumbPopover > .body').html();
        },
        container: 'body',
        placement: 'auto'
    }).on("mouseenter",function () {
        var _this = this; // thumbcontainer

        console.log('thumbcontainer mouseenter')
        // clear the counter
        clearTimeout(counter);
        // Close all other Popovers
        $('.thumbcontainer').not(_this).popover('hide');

        // start new timeout to show popover
        counter = setTimeout(function(){
            if($(_this).is(':hover'))
            {
                $(_this).popover("show");
            }
            $(".popover").on("mouseleave", function () {
                $('.thumbcontainer').popover('hide');
            });
        }, 400);

    }).on("mouseleave", function () {
        var _this = this;

        setTimeout(function () {
            if (!$(".popover:hover").length) {
                if(!$(this).is(':hover'))
                {
                    $(_this).popover('hide');
                }
            }
        }, 200);
    });
}
0
Johannes Ferner

Dies ist mein Code für QuickInfos zur Showdynamik mit Verzögerung und wird von Ajax geladen.

$(window).on('load', function () {
    generatePopovers();
    
    $.fn.dataTable.tables({ visible: true, api: true }).on('draw.dt', function () {
        generatePopovers();
    });
});

$(document).ajaxStop(function () {
    generatePopovers();
});
function generatePopovers() {
var popover = $('a[href*="../Something.aspx"]'); //locate the elements to popover

popover.each(function (index) {
    var poplink = $(this);
    if (poplink.attr("data-toggle") == null) {
        console.log("RENDER POPOVER: " + poplink.attr('href'));
        poplink.attr("data-toggle", "popover");
        poplink.attr("data-html", "true");
        poplink.attr("data-placement", "top");
        poplink.attr("data-content", "Loading...");
        poplink.popover({
            animation: false,
            html: true,
            trigger: 'manual',
            container: 'body',
            placement: 'top'
        }).on("mouseenter", function () {
            var thispoplink = poplink;
            setTimeout(function () {
                if (thispoplink.is(":hover")) {
                    thispoplink.popover("show");
                    loadDynamicData(thispoplink); //load data by ajax if you want
                    $('body .popover').on("mouseleave", function () {
                        thispoplink.popover('hide');
                    });
                }
            }, 1000);
        }).on("mouseleave", function () {
            var thispoplink = poplink;
            setTimeout(function () {
                if (!$("body").find(".popover:hover").length) {
                    thispoplink.popover("hide");
                }
            }, 100);
        });
    }
});
function loadDynamicData(popover) {
    var params = new Object();
    params.somedata = popover.attr("href").split("somedata=")[1]; //obtain a parameter to send
    params = JSON.stringify(params);
    //check if the content is not seted
    if (popover.attr("data-content") == "Loading...") {
        $.ajax({
            type: "POST",
            url: "../Default.aspx/ObtainData",
            data: params,
            contentType: "application/json; charset=utf-8",
            dataType: 'json',
            success: function (data) {
                console.log(JSON.parse(data.d));
                var dato = JSON.parse(data.d);
                if (dato != null) {
                    popover.attr("data-content",dato.something); // here you can set the data returned
                    if (popover.is(":hover")) {
                        popover.popover("show"); //use this for reload the view
                    }
                }
            },

            failure: function (data) {
                itShowError("- Error AJAX.<br>");
            }
        });
    }
}
0
Giuliano