Как я могу сохранить bootstrap popover вживую, пока popover завис?

Я использую twitter boostrap popover для создания карты наведения для отображения информации о пользователе, и я запускаю popover on mouseover check jsfiddle здесь, Я хочу, чтобы этот popover был жив, пока он парил.

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

Вы можете думать о работе карты наводки Facebook. Я хочу сделать то же самое. Как я могу это сделать?

Ответ 1

Я пришел после другого решения для этого... вот код

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

Ответ 2

Просмотрите этот рабочий код в Plunker

Небольшая модификация (из решения, предоставленного vikas), в соответствии с моим вариантом использования.
1. Откройте popover on hover для кнопки popover
2. Держите popover открытым при наведении указателя мыши на поле
3. Закройте popover на мышином слое либо для кнопки popover, либо для поля popover.

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

Играйте с ним в Plunker

Ответ 3

Здесь мой прием: http://jsfiddle.net/WojtekKruszewski/Zf3m7/22/

Иногда, перемещая мышь из popover trigger в фактический popover контент по диагонали, вы наводите на себя элементы ниже. Я хотел справиться с такими ситуациями - до тех пор, пока вы достигнете содержимого popover до того, как произойдет тайм-аут, вы будете в безопасности (popover не исчезнет). Для этого требуется delay вариант.

Этот хак в основном переопределяет функцию Popover leave, но вызывает оригинал (который запускает таймер, чтобы скрыть popover). Затем он прикрепляет одноразовый слушатель к элементу содержимого mouseenter popover content.

Если мышь входит в popover, таймер очищается. Затем он переключает его на mouseleave на 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)
  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 monitor popover content instead
      container.one('mouseleave', function(){
        $.fn.popover.Constructor.prototype.leave.call(self, self);
      });
    })
  }
};

Ответ 4

Я использовал триггер, установленный для hover и передал набор контейнера #element и, наконец, добавил расположение box right.

Это должно быть вашей настройкой:

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

и #example css нужна position:relative; проверьте jsfiddle ниже:

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

отредактированный

Эта скрипка имеет обе ссылки, которые работают без проблем http://jsfiddle.net/davidchase03/FQE57/4/

Ответ 5

Я думаю, что простой способ:

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

Таким образом, popover создается внутри самого целевого элемента. поэтому, когда вы наводите мышь на popover, она все еще над элементом. Bootstrap 3.3.2 хорошо работает с этим. У старой версии могут быть проблемы с анимацией, поэтому вы можете отключить "animation: false"

Ответ 6

Вот как я сделал это с помощью bootstrap popover с помощью других бит вокруг сети. Динамически получает название и контент от различных продуктов, отображаемых на сайте. Каждый продукт или popover получает уникальный идентификатор. Popover исчезнет при выходе из продукта ($ this.pop) или popover. Тайм-аут используется, когда будет отображаться popover до выхода через продукт вместо 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();
    };

Ответ 7

Вот решение, которое я разработал, который, кажется, хорошо работает, а также позволяет использовать обычную реализацию Bootstrap для включения всех popovers.

Оригинальная скрипка: https://jsfiddle.net/eXpressive/hfear592/

Поправлено на этот вопрос:

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

Ответ 8

Ответ Vikas отлично работает для меня, здесь я также добавляю поддержку задержки (show/hide).

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

Также обратите внимание, что я изменил:

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

с:

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

так что он ссылается именно на этот открытый popover, а не на какой-либо другой (так как теперь через задержку может быть открыто одновременно более 1)

Ответ 9

Выбранный ответ работает, но не будет выполнен, если popover инициализируется с помощью body в качестве контейнера.

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

Решение, основанное на выбранном ответе, представляет собой следующий код, который необходимо разместить перед использованием 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);
            });
        })
    }
};

Изменение минимально, используя self.$tip вместо того, чтобы пересекать DOM, ожидая, что popover будет всегда братьями и сестрами элемента.

Ответ 10

Я согласен с тем, что лучший способ - использовать один из следующих: David Chase, Cu Ly и другие, что самый простой способ сделать это - использовать container: $(this) следующим образом:

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

Я хочу указать здесь, что popover в этом случае наследует все свойства текущего элемента. Так, например, если вы сделаете это для элемента .btn (bootstrap), , вы не сможете выбрать текст внутри popover. Просто хотел записать это, так как я потратил довольно много времени, ударяя головой об этом.

Ответ 11

Просто :)

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

Ответ 12

То же самое для всплывающих подсказок:

Для меня следующее решение работает, потому что оно не добавляет прослушивателей событий в каждый "центр мыши", и можно вернуться на элемент подсказки, который поддерживает всплывающую подсказку.

$ ->

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

Ответ 13

Это решение получилось для меня прекрасным: (теперь его пуленепробиваемый); -)

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

Ответ 14

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

Ответ 15

Я обнаружил, что mouseleave не срабатывает, когда происходят странные вещи, например, внезапно меняется фокус окна, а затем пользователь возвращается в браузер. В таких случаях mouseleave никогда не будет стрелять, пока курсор не перейдет и снова покинет элемент.

Это решение, которое я придумал, полагается на mouseenter на объект window, поэтому оно исчезает, когда мышь перемещается где-нибудь еще на странице.

Это было разработано для работы с несколькими элементами на странице, которые будут запускать его (например, в таблице).

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

Ответ 16

Он будет более гибким с 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);
    } 
)

Ответ 17

Это мой код для отображения подсказок по динамике с задержкой и загрузкой с помощью ajax.

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

$(document).ajaxStop(function () {
    generatePopovers();
});