it-swarm.com.ru

Как я могу держать Twitter Bootstrap Popover открытым до тех пор, пока в него не войдет моя мышь?

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

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

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

50
Tinyfool

Теперь я просто переключаюсь на webuiPopover, он просто работает.

0
Tinyfool

С помощью 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 (). Надеюсь, это поможет.

31
marchello

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

var timeoutObj;
$('.nav_item a').popover({
    offset: 10,
    trigger: 'manual',
    html: true,
    placement: 'right',
    template: '<div class="popover" onmouseover="clearTimeout(timeoutObj);$(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 ref = $(this);
    timeoutObj = setTimeout(function(){
        ref.popover('hide');
    }, 50);
});
26
Kevin Lawrence

Бутстрап 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;
}

РАБОЧАЯ ДЕМО

26
Fizzix

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

$(".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 помогает обеспечить время для перехода от триггерной ссылки к поповеру.

19
clem

Эта проблема на загрузочном 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'});
});  
11
stevendaniels

Вот мой взгляд: http://jsfiddle.net/WojtekKruszewski/Zf3m7/22/

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

Этот хак в основном переопределяет функцию Popover leave, но вызывает оригинал (который запускает таймер, чтобы скрыть поповер). Затем он присоединяет одноразового слушателя к элементам содержимого mouseenter 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's monitor popover content instead
      container.one('mouseleave', function(){
        $.fn.popover.Constructor.prototype.leave.call(self, self);
      });
    })
  }
};
4
Wojtek Kruszewski

Решение сработало у нас для 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
Opcrat

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

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)

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

1
vinit

Наконец я исправляю эту проблему. Popover исчезает, потому что Popover не дочерний узел ссылки, это дочерний узел тела.

Так что исправить это легко, измените содержимое bootstrap-twipsy.js:

изменить .prependTo(document.body) на .prependTo(this.$element)

и исправить проблему положения, вызванную изменением.

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

1
Tinyfool

Это работает для меня на 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
ShogunPanda

Это версия решения Войтека Крушевского. В этой версии всплывающее окно мигает, когда мышь возвращается к срабатыванию. http://jsfiddle.net/danielgatis/QtcpD/

(function($) {
      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) {
          var current = $(obj.currentTarget);
          var container = current.siblings(".popover");
          container.on("mouseenter", function() {
            clearTimeout(self.timeout);
          });
          container.on("mouseleave", function() {
            originalLeave.call(self, self);
          });
        }
      };

      var originalEnter = $.fn.popover.Constructor.prototype.enter;
      $.fn.popover.Constructor.prototype.enter = function(obj) {
        var self = (obj instanceof this.constructor ? obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data("bs." + this.type));
        clearTimeout(self.timeout);
        if (!$(obj.currentTarget).siblings(".popover:visible").length) {
          originalEnter.call(this, obj);
        }
      };
    })(jQuery);
1
danielgatis

Я пробовал решения от @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
1
Micah Winkelspecht

В конце беседы, связанной @stevendaniels, есть ссылка на расширение Bootstrap в Твиттере под названием BootstrapX - clickover от Ли Кармайкла. Это превращает всплывающую подсказку из всплывающей подсказки в интерактивный элемент управления, который можно закрыть, нажав в другом месте формы, кнопку закрытия или после истечения времени ожидания. Его легко использовать, и он работал очень хорошо для проекта, в котором я нуждался. Некоторые примеры его использования можно найти здесь .

0
Miika L.

Мне не понравился ни один из найденных ответов, поэтому я скомбинировал несколько близких ответов, чтобы создать следующий код. Это позволяет вам в итоге просто набирать $(selector).pinnablepopover(options); каждый раз, когда вы хотите сделать «закрепляемый» поповер.

Код, который делает вещи проще:

$.fn.popoverHoverShow = function ()
{
    if(this.data('state') !== 'pinned')
    {
        if(!this.data('bs.popover').$tip || (this.data('bs.popover').$tip && this.data('bs.popover').$tip.is(':hidden')))
        {
            this.popover('show');
        }
    }
};
$.fn.popoverHoverHide = function ()
{
    if (this.data('state') !== 'pinned')
    {
        var ref = this;
        this.data('bs.popover').$tip.data('timeout', setTimeout(function(){ ref.popover('hide') }, 100))
        .on('mouseenter', function(){ clearTimeout($(this).data('timeout')) })
        .on('mouseleave', function(){ $(this).data('timeout', setTimeout(function(){ ref.popover('hide') }, 100)) });
        this.on('mouseenter', function(){ clearTimeout($(this).data('timeout')) });
    }
};
$.fn.popoverClickToggle = function ()
{
    if (this.data('state') !== 'pinned')
    {
        this.data('state', 'pinned');
    }
    else
    {
        this.data('state', 'hover')
    }
};
$.fn.pinnablepopover = function (options)
{
    options.trigger = manual;
    this.popover(options)
    .on('mouseenter', function(){ $(this).popoverHoverShow() })
    .on('mouseleave', function(){ $(this).popoverHoverHide() })
    .on('click', function(){ $(this).popoverClickToggle() });
};

Пример использования:

$('[data-toggle=popover]').pinnablepopover({html: true, container: 'body'});
0
Timothy Zorn

После просмотра всех ответов, которые я сделал, я думаю, что это будет полезно. Вы можете управлять всем, что вам нужно .. Многие ответы не вызывают задержку показа. Я использую это. Его работа очень хорошая в моем проекте
/****** /************************************ ************************* /

<div class='thumbnail' data-original-title=''  style='width:50%'>    
 <div id='item_details' class='popper-content hide'>
    <div>
        <div style='height:10px'> </div>
        <div class='title'>Bad blood </div>
        <div class='catagory'>Music </div>
    </div>

  </div>
  HELLO POPOVER
</div>"

/ **************** КОД СКРИПТА ****************** ПОЖАЛУЙСТА, ИСПОЛЬЗУЙТЕ ОТ СЛУХА ****** /

$(".thumbnail").popover({
trigger: "manual" ,
html: true,
animation:true,
container: 'body',
placement: 'auto right',
content: function () {
    return $(this).children('.popper-content').html();
}}) .on("mouseenter", function () {
var _this = this;

$('.thumbnail').each(function () {
    $(this).popover('hide');
});
setTimeout(function(){
    if ($(_this).is(':hover')) {
        $(_this).popover("show");
    }
},1000);
$(".popover").on("mouseleave", function () {
    $('.thumbnail').each(function () {
        $(this).popover('hide');
    });
    $(_this).popover('hide');
 }); }).on("mouseleave", function () {
    var _this = this;
    setTimeout(function () {
        if (!$(".popover:hover").length) {
            $(_this).popover("hide");
        }
    }, 100); });
0
Ashaduzaman Bhuiyan