Jak mogę utrzymać przy życiu wyskakujące okienka Bootstrap podczas unoszenia się?


114

Używam wyskakującego okienka Bootstrap, aby utworzyć wizytówkę pokazującą informacje o użytkowniku i uruchamiam ją po najechaniu kursorem myszy na przycisk. Chcę utrzymać ten popover przy życiu, gdy sam popover jest najeżdżany, ale znika, gdy tylko użytkownik przestanie najeżdżać na przycisk. W jaki sposób mogę to zrobić?

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

$(document).on('mouseover', '#example', function(){
    $('#example').popover('show');
});

$(document).on('mouseleave', '#example', function(){
    $('#example').popover('hide');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.js"></script>
<script src="https://unpkg.com/@popperjs/core@2"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>

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


chcesz zachować to przy życiu? najechałem na przycisk i został on otwarty?
David Chase,

przeczytaj ostatnią linijkę pytania
vikas devde

Odpowiedzi:


172

Przetestuj z fragmentem kodu poniżej:

Mała modyfikacja (z rozwiązania dostarczonego przez Vikas), aby pasowała do mojego przypadku użycia.

  1. Otwórz zdarzenie Popover on hover dla przycisku Popover
  2. Pozostaw okno popover otwarte po najechaniu kursorem na okienko popover
  3. Zamknij wyskakujące okienko na mouseleave dla przycisku wyskakującego lub okienka podręcznego.

$(".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);
  });
<!DOCTYPE html>
<html>

<head>
  <link data-require="bootstrap-css@*" data-semver="3.2.0" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
  <script data-require="jquery@*" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script data-require="bootstrap@*" data-semver="3.2.0" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.js"></script>

  <link rel="stylesheet" href="style.css" />

</head>

<body>
  <h2 class='text-primary'>Another Great "KISS" Bootstrap Popover example!</h2>
  <p class='text-muted'>KISS = Keep It Simple S....</p>

  <p class='text-primary'>Goal:</p>
  <ul>
    <li>Open popover on hover event for the popover button</li>
    <li>Keep popover open when hovering over the popover box</li>
    <li>Close popover on mouseleave for either the popover button, or the popover box.</li>
  </ul>

  <button type="button" class="btn btn-danger pop" data-container="body" data-toggle="popover" data-placement="right" data-content="Optional parameter: Skip if this was not requested<br>                                    A placement group is a logical grouping of instances within a single Availability                                     Zone. Using placement groups enables applications to get the full-bisection bandwidth                                     and low-latency network performance required for tightly coupled, node-to-node                                     communication typical of HPC applications.<br>                                    This only applies to cluster compute instances: cc2.8xlarge, cg1.4xlarge, cr1.8xlarge, hi1.4xlarge and hs1.8xlarge.<br>                                    More info: <a href=&quot;http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html&quot; target=&quot;_blank&quot;>Click here...</a>"
    data-original-title="" title="">
    HOVER OVER ME
    </button>
  <br><br>
  <button type="button" class="btn btn-info pop" data-container="body" data-toggle="popover" data-placement="right" data-content="Optional parameter: Skip if this was not requested<br>                                    A placement group is a logical grouping of instances within a single Availability                                     Zone. Using placement groups enables applications to get the full-bisection bandwidth                                     and low-latency network performance required for tightly coupled, node-to-node                                     communication typical of HPC applications.<br>                                    This only applies to cluster compute instances: cc2.8xlarge, cg1.4xlarge, cr1.8xlarge, hi1.4xlarge and hs1.8xlarge.<br>                                    More info: <a href=&quot;http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html&quot; target=&quot;_blank&quot;>Click here...</a>"
    data-original-title="" title="">
    HOVER OVER ME... Again!
    </button><br><br>
  <button type="button" class="btn btn-success pop" data-container="body" data-toggle="popover" data-placement="right" data-content="Optional parameter: Skip if this was not requested<br>                                    A placement group is a logical grouping of instances within a single Availability                                     Zone. Using placement groups enables applications to get the full-bisection bandwidth                                     and low-latency network performance required for tightly coupled, node-to-node                                     communication typical of HPC applications.<br>                                    This only applies to cluster compute instances: cc2.8xlarge, cg1.4xlarge, cr1.8xlarge, hi1.4xlarge and hs1.8xlarge.<br>                                    More info: <a href=&quot;http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html&quot; target=&quot;_blank&quot;>Click here...</a>"
    data-original-title="" title="">
    Okay one more time... !
    </button>
  <br><br>
  <p class='text-info'>Hope that helps you... Drove me crazy for a while</p>
  <script src="script.js"></script>
</body>

</html>


To działa idealnie, zauważyłem, że brakowało ;w tobie sekundy $(_this).popover("hide"). Ale dziękuję, to było takie proste i czyste!
kozioł ofiarny

3
Ta odpowiedź jest niesamowita. Działa świetnie na BS3 od maja 2015 ^^
zdegenerowany

1
Użyłem go w tabeli i dodałem container: 'body'do opcji, ponieważ spowodowało to przesunięcie komórek. Świetna odpowiedź!
Alexander Derck

Popover zostanie ukryty, jeśli wejdziesz do niego, a następnie wrócisz do elementu wyzwalającego wszystko przed 300 ms. Aby to naprawić, sprawdź, czy ZARÓWNO popover, jak i jego wyzwalacz to: hover przed ukryciem go w setTimeout. Użyłbym również setTimeout i tego samego podejścia na mouseleave samego popover, aby naprawić migotanie.
rzb

Upewnij się, że ustawiłeś, animation:falseaby naprawić migotanie - sprawdź link Plunker, który mam powyżej. U mnie działa idealnie.
OkezieE

84

Przyszedłem po innym rozwiązaniu tego ... oto kod

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

6
Jest ważne, aby dodać animation: falseinaczej przesunięcie myszy nad linkiem wielokrotnie spowoduje, że nie działa poprawnie
jasop

5
Mam małą modyfikację twojego kodu @vikas ( gist.github.com/Nitrodist/7913848 ). Po 50 ms ponownie sprawdza stan, aby nie pozostawał otwarty. Oznacza to, że stale sprawdza go ponownie co 50 ms.
Nitrodist,

2
Jak można to dostosować, aby działało na aktywnych elementach właśnie dodanych do dokumentu?
williamsowen

28

Oto moje podejście: http://jsfiddle.net/WojtekKruszewski/Zf3m7/22/

Czasami podczas przesuwania myszy od wyzwalacza wyskakującego okienka do rzeczywistej zawartości okna podręcznego po przekątnej , najeżdżasz na elementy poniżej. Chciałem poradzić sobie z takimi sytuacjami - o ile dotrzesz do zawartości popover, zanim upłynie limit czasu, jesteś bezpieczny (popover nie zniknie). To wymagadelay opcji.

Ten hack zasadniczo zastępuje leavefunkcję Popover , ale wywołuje oryginał (który uruchamia licznik czasu, aby ukryć popover). Następnie dołącza jednorazowy odbiornik do mouseenterpopover elementu zawartości.

Jeśli mysz wejdzie w okienko popover, licznik czasu zostanie wyczyszczony. Następnie włącza nasłuchiwanie mouseleavepo wyskakiwaniu i jeśli jest wyzwalany, wywołuje oryginalną funkcję wyjścia, aby mogła rozpocząć ukrywanie licznika czasu.

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

5
Znalezienie kontenera można ulepszyć za pomocą W container = self.$tip;ten sposób popover można znaleźć nawet wtedy, gdy containerwłaściwość jest ustawiona. Jest tu skrzypce: jsfiddle.net/dennis_c/xJc65
dbroeks

3
@pferrel Rozwiązałem ten problem w moim widelcu skrzypiec @Wojtek_Kruszewski : jsfiddle.net/HugeHugh/pN26d zobacz część, która sprawdza if (!thisTip.is(':visible'))przed wywołaniemoriginalShow()
H Dog

1
Jeśli popover zostanie zainicjowany z opcją, container: 'body',to rozwiązanie nie będzie działać zgodnie z oczekiwaniami. Zmienna containermusi zostać zastąpiona przez self.$tip. Sprawdź moją odpowiedź, aby uzyskać więcej informacji: stackoverflow.com/a/28731847/439427
Rubens Mariuzzo

1
Znakomity. Działa to w przypadku używania parametru „selector”, w przeciwieństwie do innych odpowiedzi.
jetlej

1
Oto ulepszona wersja, która naprawia błąd przy wyjściu i ponownym wejściu do końcówki nadal ją ukrywała, a także naprawia scenariusz, gdy końcówka jest przymocowana do ciała jsfiddle.net/Zf3m7/1499
Zoltán Tamási

14

Myślę, że prostym sposobem byłoby to:

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

W ten sposób popover jest tworzony wewnątrz samego elementu docelowego. więc kiedy przesuniesz kursor myszy nad popover, nadal będzie on nad elementem. Bootstrap 3.3.2 działa z tym dobrze. Starsza wersja może mieć problemy z animacją, więc możesz chcieć wyłączyć „animation: false”


Wiem, że ten wątek jest stary, ale to moim zdaniem najlepsze, najczystsze rozwiązanie i powinno być wyżej. Jedynym zastrzeżeniem jest to, że to się zepsuje, jeśli umieścisz popover (w dziwny sposób) „z dala” od elementu wyzwalającego. Ale dopóki odległość między nimi wynosi zero (np. Zachodzą na siebie), działa to pięknie i nie wymaga żadnego niestandardowego JS. Dziękuję Ci!
JohnGalt

To jak dotąd najlepsze, czyste i najłatwiejsze rozwiązanie. Powinien być wyżej w rankingu! Dodałem delay: { "hide": 400 }trochę opóźnienia przed ukryciem i działa świetnie! 👍
coorasse

14

Użyłem wyzwalacza ustawionego na hoveri dałem zestaw kontenera na #elementi ostatecznie dodając umieszczenie elementu boxto right.

To powinna być Twoja konfiguracja:

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

a #examplecss musi position:relative;sprawdzić poniższy jsfiddle:

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

Edytowano

To skrzypce ma oba linki, które działają bez problemów http://jsfiddle.net/davidchase03/FQE57/4/


hmm to działa, mogę użyć jquery ajax w contentopcji, aby zabrać zawartość z serwera side..will że pracy lub muszę zrobić kilka dodatkowych prac za to
Vikas devde

@vikasdevde tak można użyć ajaxw treści, ale musisz ustawić się za to do pracy ... proszę zaznaczyć odpowiedź rację jeśli to rozwiązało OP.. więc inni mogą korzystać
David Chase

ale jeśli używamy samego łącza jako pojemnik następnie cała popover staje link .... spróbować
Vikas devde

jeśli umieścisz link w pudełku, będzie on nadal znajdował się… prawda?
David Chase,

2
Żaden z jsfiddle nie działa dla mnie. Chrome 20 marca 2014 r.
pferrel

7

Tak zrobiłem z popover bootstrap z pomocą innych bitów w sieci. Dynamicznie pobiera tytuł i treść z różnych produktów wyświetlanych na stronie. Każdy produkt lub popover otrzymuje unikalny identyfikator. Popover zniknie po wyjściu z produktu ($ this .pop) lub popover. Limit czasu jest używany, gdy wyświetli popover do wyjścia przez produkt zamiast popover.

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

Działa to również, jeśli popover nie jest elementem podrzędnym elementu docelowego. +1
Taha Paksu

6

Oto rozwiązanie, które wymyśliłem, które wydaje się działać dobrze, a jednocześnie umożliwia użycie normalnej implementacji Bootstrap do włączania wszystkich okien popover.

Oryginalne skrzypce: https://jsfiddle.net/eXpressive/hfear592/

Przeniesiony do tego pytania:

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

2

Zgadzam się, że najlepiej jest skorzystać z tego, który podali: David Chase , Cu Ly i inni, że najprostszym sposobem jest użycie container: $(this)właściwości w następujący sposób:

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

Chcę tutaj zaznaczyć, że popover w tym przypadku odziedziczy wszystkie właściwości bieżącego elementu . Na przykład, jeśli zrobisz to dla .btnelementu (bootstrap), nie będziesz w stanie zaznaczyć tekstu w wyskakującym okienku . Chciałem to tylko nagrać, ponieważ spędziłem trochę czasu, waląc w to głową.


1

Odpowiedź Vikasa działa u mnie idealnie, tutaj dodam również obsługę opóźnienia (pokaż / ukryj).

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

Zwróć też uwagę, że zmieniłem:

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

z:

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

tak, że odwołuje się dokładnie do tego otwartego okna popover, a nie do żadnego innego (ponieważ teraz, z powodu opóźnienia, więcej niż 1 może być otwarte w tym samym czasie)


Komentarz, który zrobiłem na końcu, w rzeczywistości nie jest właściwy, gdy używam container: body, jeśli tak, nadal muszę użyć rozwiązania Vikasa dla tej jednej linii
user1993198

1

Wybrana odpowiedź działa, ale zakończy się niepowodzeniem, jeśli popover zostanie zainicjowany z bodykontenerem.

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

Rozwiązaniem opartym na wybranej odpowiedzi jest poniższy kod, który należy umieścić przed użyciem popover.

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

Zmiana jest minimalna przy użyciu self.$tipzamiast przechodzenia przez DOM, oczekując, że popover będzie zawsze rodzeństwem elementu.


0

To samo dotyczy podpowiedzi:

Dla mnie poniższe rozwiązanie działa, ponieważ nie dodaje detektorów zdarzeń na każdym „środku myszy” i można ponownie najechać kursorem na element podpowiedzi, który utrzymuje etykietkę przy życiu.

$ ->

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

To rozwiązanie zadziałało dla mnie dobrze: (teraz jest kuloodporne) ;-)

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

Zauważyłem, że mouseleavenie uruchomi się, gdy zdarzają się dziwne rzeczy, na przykład nagle zmienia się fokus okna, a następnie użytkownik wraca do przeglądarki. W takich przypadkachmouseleave nigdy się nie uruchomi, dopóki kursor nie przejdzie i nie opuści elementu.

To rozwiązanie, które wymyśliłem, opiera się mouseenterna windowobiekcie, więc znika, gdy mysz zostanie przesunięta w inne miejsce strony.

Zostało to zaprojektowane do pracy z wieloma elementami na stronie, które ją wywołają (jak w tabeli).

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

Będzie bardziej elastyczny dzięki 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

Prosty :)

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

0

Niedawno potrzebowałem, aby to działało z KO, a powyższe rozwiązania nie działały dobrze, gdy miałem opóźnienia w pokazaniu i ukryciu. Poniższe informacje powinny to naprawić. Na podstawie tego, jak działają podpowiedzi bootstrap. Mam nadzieję, że to komuś pomoże.

var options = {
                delay: { show: 1000, hide: 50 },
                trigger: 'manual',                      
                html: true
            };
var $popover = $(element).popover(options);

$popover.on('mouseenter', function () { // This is entering the triggering element
    var self = this;

    clearTimeout(self.timeout);
    self.hoverState = 'in';

    self.timeout = setTimeout(function () {
        if (self.hoverState == 'in') {
            $(self).popover("show");

            $(".popover, .popover *").on('mouseover', function () { // This is moving over the popover
                clearTimeout(self.timeout);
            });                                                                 

            $(".popover").on('mouseleave', function () { // This is leaving the popover
                self.timeout = setTimeout(function () {
                    if (self.hoverState == 'out') {
                        $(self).popover('hide');
                    }
                }, options.delay.hide);
            });
        }
    }, options.delay.show);
}).on('mouseleave', function (event) { // This is leaving the triggering element
    var self = this;

    clearTimeout(self.timeout);
    self.hoverState = 'out';

    self.timeout = setTimeout(function () {                             
        if (self.hoverState == 'out') {
            $(self).popover('hide');
        }

    }, options.delay.hide);
});

-1

To jest mój kod do wyświetlania podpowiedzi dynamiki z opóźnieniem i ładowany przez ajax.

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.