Как я могу держать Twitter Bootstrap Popover открытым, пока моя мышь не перейдет в него?
У меня есть ссылка, которая использует Twitter Bootstrap Popover версия 1.3.0 чтобы показать некоторую информацию. Эта информация включает ссылку, но каждый раз, когда я перемещаю мышь от ссылки к popover, popover просто исчезает.
Как я могу держать popover открытым достаточно долго, чтобы мышь могла двигаться в него? Затем, когда мышь выходит из ссылки и popover, скрыть его?
или есть какой другой плагин, который может это сделать?
16 ответов
с 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 () enabler. Надеюсь, это поможет.
просто добавьте к примеру Марчелло, если вы хотите, чтобы popover исчез, если пользователь перемещает свою мышь от popover и исходная ссылка, попробуйте это.
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);
});
Bootstrap 3 и выше
простой, просто использовать container
option и иметь его в качестве элемента, вызывающего popover. Таким образом, 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:
эта часть является необязательной, но рекомендуется. Он перемещает popover вниз на 7 пикселей для облегчения доступа.
.pop .popover {
margin-top:7px;
}
Это немного хаки, но, основываясь на примере Марчелло, я сделал это (нет необходимости в шаблоне):
$(".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
помогает гарантировать, что есть время для перехода от триггерной ссылки к popover.
эта проблема на загрузочном GitHub РЕПО занимается этой проблемой. жирный указал на экспериментальное размещение" сверху/снизу/слева/справа". Это работает, довольно хорошо, но вы должны убедиться, что триггер popover не расположен статически с css. В противном случае popover не появится там, где вы хотите.
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'});
});
вот мой дубль:http://jsfiddle.net/WojtekKruszewski/Zf3m7/22/
иногда при перемещении мыши из триггера popover в фактическое содержимое popover по диагонали, вы зависаете над элементами ниже. Я хотел справиться с такими ситуациями – пока вы достигаете контента popover до тайм-аута, вы сохраняете (popover не исчезнет). Это требует .
этот хак в основном переопределяет Popover
решение работало для нас для 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);
});
наконец, я исправляю эту проблему. Popover исчезают, потому что Popover не дочерний узел связи, это дочерний узел тела.
Так исправить это легко, изменить bootstrap-twipsy.js
содержание:
изменить .prependTo(document.body)
to .prependTo(this.$element)
и исправьте причину проблемы положения изменением.
и некоторые используют ссылку tiger popover вызовет popover со ссылкой тоже, поэтому добавьте span содержат ссылку, поэтому проблема решена.
это версия решения Войтека Крушевского. Эта версия ручка popover мигает, когда мышь возвращается к триггеру. 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);
Я пробовал решения от @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
вот что я сделал:
e = $("a[rel=popover]")
e.popover({
content: d,
html:true,
trigger:'hover',
delay: {hide: 500},
placement: 'bottom',
container: e,
})
Это очень простое и удивительное решение для этого probelm, которое я узнал, заглянув в код подсказки bootstrap. В Bootstrap v3.0.3 вот строка кода, которую я заметил:
this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
это говорит о том, что если container
свойство popover определяется, затем popover получает appendTo() элемент вместо insertAfter () исходный элемент, все, что вам нужно сделать, это просто передать элемент как свойство контейнера. Потому что appendTo () всплывающее окно становится частью ссылки, по которой было привязано событие наведения и, таким образом, сохраняет всплывающее окно открытым, когда мышь перемещается по нему.
это работает для меня 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();
});
в конце разговора, связанного @stevendaniels является ссылка на расширение Bootstrap Twitter под названием BootstrapX-clickover ли Кармайкл. Это изменяет всплывающее окно из всплывающей подсказки overlarge в интерактивный элемент управления, который можно закрыть, щелкнув в другом месте формы, кнопку закрытия или после тайм-аута. Его простой в использовании и работал очень хорошо для проекта, в котором я нуждался. Некоторые примеры его использования можно найти здесь.
мне не нравится ни один из ответов я нашел, поэтому я объединил некоторые ответы, которые были близки, чтобы сделать следующий код. Это позволяет в конечном итоге просто набрав $(selector).pinnablepopover(options);
каждый раз, когда вы хотите сделать "pinnable" popover.
код, который делает вещи легко:
$.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'});
после просмотра всего ответа я сделал это, я думаю, что это будет полезно .Вы можете управлять всем, что вам нужно.
Многие ответы не делают show delay я использую это. Его работа очень хорошая в моем проекте
/******
/*************************************************************/
<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>"
/****************КОД СЦЕНАРИЯ ****************** ПОЖАЛУЙСТА, ИСПОЛЬЗУЙТЕ ОТ HEAR ****** /
$(".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); });