Comment puis-je garder Bootstrap popover vivant pendant que le popover est en vol stationnaire?
j'utilise le popover de Boostrap sur twitter pour créer une carte hover pour afficher les informations de l'utilisateur, et je déclenche popover sur mouseover check jsfiddle here . Je veux garder cette liste en vie tout en étant plané.
<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');
});
vous pouvez penser à travailler de Facebook hover card. Je veux le faire de la même manière. Comment puis-je faire cela?
16 réponses
petite modification (à partir de la solution fournie par vikas) pour convenir à mon cas d'utilisation.
1. Ouvrir popover en vol stationnaire pour le bouton popover
2. Garder popover ouvert en vol stationnaire au-dessus de la boîte popover
3. Fermez popover sur mouseleave pour soit le bouton popover, soit la boîte 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);
});
je suis venu après une autre solution à cela...voici le code
$('.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);
});
Voici mon avis: http://jsfiddle.net/WojtekKruszewski/Zf3m7/22 /
parfois, en déplaçant la souris de popover trigger au contenu popover réel en diagonale , vous passez au-dessus des éléments ci-dessous. Je voulais gérer de telles situations-aussi longtemps que vous atteignez le contenu popover avant les feux d'arrêt, vous êtes en sécurité (le popover ne disparaîtra pas). Il nécessite l'option delay
.
ce piratage fondamentalement remplace Popover leave
fonction, mais appelle l'original (qui démarre la minuterie pour cacher le popover). Ensuite, il fixe un écouteur unique à l'élément de contenu popover mouseenter
.
si la souris entre dans le popover, le minuteur est dégagé. Puis il tourne il écoute à mouseleave
sur popover et s'il est déclenché, il appelle la fonction de permission originale afin qu'il puisse démarrer hide timer.
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);
});
})
}
};
j'ai utilisé le déclencheur hover
et j'ai donné le conteneur #element
et j'ai finalement ajouté un emplacement du box
à right
.
ceci devrait être votre configuration:
$('#example').popover({
html: true,
trigger: 'hover',
container: '#example',
placement: 'right',
content: function () {
return '<div class="box"></div>';
}
});
et #example
css besoins position:relative;
vérifier le jsfiddle ci-dessous:
https://jsfiddle.net/9qn6pw4p/1 /
Édité
This le violon a deux liens qui fonctionnent sans problèmes http://jsfiddle.net/davidchase03/FQE57/4 /
je pense qu'un moyen facile serait ceci:
$('.popover').each(function () {
var $this = $(this);
$this.popover({
trigger: 'hover',
content: 'Content Here',
container: $this
})
});
de cette façon le popover est créé à l'intérieur de l'élément cible lui-même. donc quand vous déplacez votre souris sur le popover, c'est toujours sur l'élément. Bootstrap 3.3.2 fonctionne bien avec cela. L'ancienne version peut avoir quelques problèmes avec l'animation, donc vous pouvez désactiver "animation: false "
C'est ce que j'ai fait avec bootstrap popover à l'aide d'autres bits autour du filet. Obtient dynamiquement le titre et le contenu des différents produits affichés sur le site. Chaque produit ou popover reçoit un identifiant unique. Liste disparaîtra lors de la sortie du produit( $this .pop) ou le popover. Timeout est utilisé où affichera le popover jusqu'à la sortie par le produit au lieu de 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();
};
Voici une solution que j'ai conçue qui semble bien fonctionner tout en vous permettant d'utiliser l'implémentation Bootstrap normale pour activer tous les popovers.
violon Original: https://jsfiddle.net/eXpressive/hfear592 /
a rapporté à cette question:
<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');
});
réponse de Vikas fonctionne parfaitement pour moi, ici j'ajoute aussi le support pour le retard (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);
});
faites aussi attention j'ai changé:
if (!$(".popover:hover").length) {
avec:
if (popover.siblings(".popover").length && !popover.siblings(".popover").is(":hover")) {
de sorte qu'il se réfère exactement à ce popover ouvert, et pas n'importe quel autre (depuis maintenant, par le retard, plus de 1 pourrait être ouvert en même temps)
La réponse choisie œuvres , mais échouera si la liste est initialisée avec la body
comme conteneur.
$('a').popover({ container: 'body' });
une solution basée sur la réponse choisie est le code suivant qui doit être placé avant d'utiliser le 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);
});
})
}
};
le changement est minime en utilisant self.$tip
au lieu de traverser le DOM s'attendant à ce que le popover soit toujours un frère de l'élément.
Simple:)
$('[data-toggle="popover"]').popover( { "container":"body", "trigger":"focus", "html":true });
$('[data-toggle="popover"]').mouseenter(function(){
$(this).trigger('focus');
});
même chose pour tooltips:
pour moi, la solution suivante fonctionne parce qu'elle n'ajoute pas d'écouteurs d'événements sur chaque 'mouseenter' et qu'il est possible de revenir sur l'élément tooltip qui maintient la tooltip en vie.
$ ->
$('.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
Cette solution a bien marché pour moi: (maintenant, ses pare-balles) ;-)
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);
});
}
$(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);
});
});
je suis d'accord que la meilleure façon est d'utiliser celui qui est donné par: David Chase , Cu Ly, et d'autres personnes que la façon la plus simple pour ce faire est d'utiliser le container: $(this)
de la propriété comme suit:
$(selectorString).each(
var $this = $(this);
$this.popover({
html: true,
placement: "top",
container: $this,
trigger: "hover",
title: "Popover",
content: "Hey, you hovered on element"
});
);
je tiens à souligner ici que le popover dans ce cas héritera de toutes les propriétés de l'élément actuel . Ainsi, par exemple ,si vous faites cela pour un élément .btn
(bootstrap), vous ne pourrez pas sélectionner texte à l'intérieur du popover . Je voulais juste enregistrer ça depuis que j'ai passé pas mal de temps à me cogner la tête sur ça.
j'ai trouvé que le mouseleave
ne se déclenche pas quand des choses bizarres se produisent, comme le focus de la fenêtre change soudainement, puis l'utilisateur revient au navigateur. Dans des cas comme celui-ci, mouseleave
ne tirera jamais jusqu'à ce que le curseur passe et quitte l'élément à nouveau.
Cette solution que j'ai trouvée s'appuie sur mouseenter
sur l'objet window
, il disparaît donc quand la souris est déplacée n'importe où ailleurs sur la page.
Cela a été conçu pour fonctionner avec plusieurs éléments sur la page qui va le déclencher (comme dans un tableau).
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");
}
});
});
il sera plus flexible avec 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);
}
)