Как я могу держать Twitter Bootstrap Popover открытым до тех пор, пока в него не войдет моя мышь? - PullRequest
50 голосов
/ 09 октября 2011

У меня есть ссылка, которая использует Twitter Bootstrap Popover версии 1.3.0 , чтобы показать некоторую информацию.Эта информация включает в себя ссылку, но каждый раз, когда я перемещаю свою мышь от ссылки к поповеру, поповер просто исчезает.

Как я могу держать поповер открытым, чтобы мышь могла двигаться в нем?Затем, когда мышь выходит из ссылки и всплывающего окна, прячется?

Или есть какой-то другой плагин, который может это сделать?

Ответы [ 16 ]

31 голосов
/ 22 февраля 2012

С помощью bootstrap (протестировано с версией 2) я выяснил следующий код:

$("a[rel=popover]")
            .popover({
                offset: 10,
                trigger: 'manual',
                animate: false,
                html: true,
                placement: 'left',
                template: '<div class="popover" onmouseover="$(this).mouseleave(function() {$(this).hide(); });"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'

            }).click(function(e) {
                e.preventDefault() ;
            }).mouseenter(function(e) {
                $(this).popover('show');
            });

Главное - это переопределить шаблон с помощью mouseleave ().Надеюсь, это поможет.

26 голосов
/ 23 мая 2014

Bootstrap 3 и выше

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

Например:

HTML:

<div class="pop" data-content="Testing 12345">This has a popover</div>
<div class="pop" data-content="Testing 12345">This has a popover</div>
<div class="pop" data-content="Testing 12345">This has a popover</div>

jQuery:

Выполнение цикла $.each() над каждым из моих элементов, которые я хочу, чтобы popover был связан с его родителем.В этом случае каждый элемент имеет класс pop.

$('.pop').each(function () {
    var $elem = $(this);
    $elem.popover({
        placement: 'top',
        trigger: 'hover',
        html: true,
        container: $elem
    });
});

CSS:

Эта часть не обязательна, но рекомендуется.Он перемещает поповер вниз на 7 пикселей для более легкого доступа.

.pop .popover {
    margin-top:7px;
}

WORKING DEMO

26 голосов
/ 05 сентября 2012

Просто добавьте к примеру Марчелло, если вы хотите, чтобы всплывающее окно исчезло, если пользователь отодвигает свою мышь от исходной ссылки и , попробуйте это.

19 голосов
/ 03 мая 2013

Это немного странно, но, основываясь на примере Марчелло, я сделал это (шаблон не нужен):

$(".trigger-link").popover({
  trigger: "manual",
}).on("click", function(e) {
  e.preventDefault();
}).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);
});

setTimeout помогает обеспечить время для перехода от триггерной ссылки.к поповеру.

11 голосов
/ 18 марта 2012

Эта проблема в репозитории начальной загрузки github решает эту проблему.Толстый указал на экспериментальное размещение "сверху / снизу / слева / справа".Это работает, довольно хорошо, но вы должны убедиться, что триггер popover не расположен статически с css.В противном случае всплывающее окно не появится там, где вы хотите.

HTML:

<span class="myClass" data-content="lorem ipsum content" data-original-title="pop-title">Hover me to show a popover.</span>

CSS:

/*CSS */
.myClass{ position: relative;}

JS:

$(function(){
  $('.myClass').popover({placement: 'in top'});
});  
4 голосов
/ 09 октября 2013

Решение сработало у нас для Bootstrap 3.

var timeoutObj;
$('.list-group a').popover({
    offset: 10,
    trigger: 'manual',
    html: true,
    placement: 'right',
    template: '<div class="popover" onmouseover="$(this).mouseleave(function() {$(this).hide();});"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
}).mouseenter(function(e) {
    $(this).popover('show');
}).mouseleave(function(e) {
    var _this = this;
    setTimeout(function() {
        if (!$(".popover:hover").length) {
            $(_this).popover("hide");
        }
    }, 100);
}); 
4 голосов
/ 02 сентября 2013

Вот мое мнение: http://jsfiddle.net/WojtekKruszewski/Zf3m7/22/

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

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

Если мышь входит в поповер, таймер очищается.Затем он слушает mouseleave при всплывающем окне и, если он срабатывает, вызывает исходную функцию выхода, чтобы запустить таймер скрытия.

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);
      });
    })
  }
};
1 голос
/ 10 декабря 2014

Это работает для меня на BootStrap 3 :

el.popover({
  delay: {hide: 100}
}).on("shown.bs.popover", function(){
  el.data("bs.popover").tip().off("mouseleave").on("mouseleave", function(){
    setTimeout(function(){
      el.popover("hide");
    }, 100);
  });
}).on("hide.bs.popover", function(ev){
  if(el.data("bs.popover").tip().is(":hover"))
    ev.preventDefault();
});
1 голос
/ 04 марта 2014

Вот что я сделал:

e = $("a[rel=popover]")
e.popover({
    content: d, 
    html:true, 
    trigger:'hover',
    delay: {hide: 500},
    placement: 'bottom',
    container: e, 
})

Это очень простое и удивительное решение этой проблемы, которое я узнал, посмотрев код подсказки начальной загрузки. В Bootstrap v3.0.3 вот строка кода, которую я заметил:

this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)

это говорит о том, что если определено container свойство popover, тогда popover получает appendTo () элемент вместо insertAfter () исходного элемента, все, что вам нужно сделать, это просто передать элемент как свойство контейнера. Из-за appendTo () всплывающее окно становится частью ссылки, по которой было связано событие наведения, и, таким образом, сохраняет всплывающее окно открытым при наведении на него мыши.

1 голос
/ 07 сентября 2013

Я попробовал решения от @Wotjek Kruszewski и @danielgatis, но ни один из них не работал для меня.Предостережение: я использую Bootstrap v2.1.0, а не v3.Это решение написано в coffeescript (почему люди все еще используют простой javascript? =)).

(($) ->
  originalLeave = $.fn.popover.Constructor::leave
  $.fn.popover.Constructor::leave = (e) ->
    self = $(e.currentTarget)[@type](@_options).data(@type)
    originalLeave.call @, e

    if e.currentTarget
      container = $(".popover")
      container.one "mouseenter", ->
        clearTimeout self.timeout

        container.one "mouseleave", ->
          originalLeave.call self, e
) jQuery
...