Ответ 1
Теперь я просто переключаюсь на webuiPopover, он просто работает.
У меня есть ссылка, которая использует Twitter Bootstrap Popover версии 1.3.0, чтобы показать некоторую информацию. Эта информация включает ссылку, но каждый раз, когда я перемещаю мышь из ссылки на popover, popover просто исчезает.
Как я могу держать popover открытым достаточно долго, чтобы позволить мыши перемещаться в него? Затем, когда мышь выйдет из ссылки и поместится, скройте ее?
Или есть ли другой плагин, который может это сделать?
Теперь я просто переключаюсь на webuiPopover, он просто работает.
С 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. Надеюсь, это поможет.
Просто добавьте пример Marchello, если вы хотите, чтобы popover исчез, если пользователь отталкивает свою мышь от ссылки 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);
});
Просто используйте параметр container
и используйте его как элемент, вызывающий 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;
}
Это немного взломанный, но, основываясь на примере marchello, я сделал это (нет необходимости в шаблоне):
$(".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.
Эта проблема в репозитории bootstrap 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 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);
});
})
}
};
Решение работало для нас для 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 не дочерний node ссылки, это дочерний элемент node тела.
Так что исправить это легко, измените bootstrap-twipsy.js
содержимое:
измените .prependTo(document.body)
на .prependTo(this.$element)
и устранить проблему с положением позиции путем изменения.
а некоторые используют ссылку tiger popover, также вызовут popover со ссылкой, поэтому добавьте ссылку на span, чтобы решить проблему.
Это версия решения Wojtek Kruszewski. Эта рукописная надпись версии мигает, когда мышь возвращается к триггеру. 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, но ни один из них не работал у меня. Caveat: Я использую 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,
})
Это очень простое и удобное решение этой проблемы, которое я узнал, просмотрев код всплывающей подсказки. В Bootstrap v3.0.3 вот строка кода, которую я заметил:
this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
это говорит о том, что если свойство container
свойства popover определено, то popover получает appendTo() элемент вместо insertAfter() исходного элемента, все, что вам нужно сделать, это просто передать элемент как свойство контейнера. Из-за appendTo() popover становится частью ссылки, на которой было привязано событие hover, и таким образом сохраняет popover открытым, когда мышь перемещается по нему.
Это работает для меня на 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 Ли Кармайкл. Это изменяет popover из всплывающей подсказки в интерактивный элемент управления, который можно закрыть, щелкнув в другом месте формы, кнопку закрытия или после таймаута. Он прост в использовании и очень хорошо работал для проекта, в котором я нуждался. Некоторые примеры его использования можно найти здесь.
Мне не понравился ни один из ответов, которые я нашел, поэтому я собрал несколько ответов, которые были близки к составлению следующего кода. Это позволяет вам просто набирать $(selector).pinnablepopover(options);
каждый раз, когда вы хотите создать "прыгающий" 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'});
После просмотра всего ответа я сделал это, я думаю, это будет полезно. Вы можете управлять всем, что вам нужно.
Многие ответы не делают задержку отображения, я использую это. Его работа очень приятная в моем проекте
/******
/************************************************* ************/
<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>"
/**************** SCRIPT КОД ****************** ПОЖАЛУЙСТА, ИСПОЛЬЗУЙТЕ ИЗ СЕРДЦА **** **/
$(".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); });