J'utilise popover de Twitter boostrap pour créer une carte de survol pour afficher les informations des utilisateurs, et je déclenche une popover lors du contrôle de la souris jsfiddle ici. Je veux garder ce popover en vie pendant son vol stationnaire.
<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 au travail de la carte de survol de Facebook. Je veux le faire de la même manière. Comment puis-je faire ceci?
Je suis venu après une autre solution à ceci ... 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);
});
Petite modification (de la solution fournie par vikas) pour convenir à mon cas d'utilisation.
1. Ouvrir l'événement Popover on Hover pour le bouton popover
2. Garder popover ouvert lorsque vous survolez la boîte popover
3. Fermez Popover sur Mouseleave pour le bouton Popover ou 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);
});
Voici ce que je pense: http://jsfiddle.net/WojtekKruszewski/Zf3m7/22/
Parfois, lorsque vous déplacez la souris d'un déclencheur popover à son contenu diagonalement, vous survolez les éléments ci-dessous. Je voulais gérer de telles situations - tant que vous atteignez le contenu popover avant le délai expiré, vous êtes en sécurité (la popover ne disparaîtra pas). Il nécessite l'option delay
.
Ce hack annule fondamentalement la fonction Popover leave
, mais appelle l'original (qui démarre le minuteur pour masquer la popover). Ensuite, il attache un auditeur unique à l'élément de contenu mouseenter
popover.
Si la souris entre dans le popover, la minuterie est effacée. Ensuite, il passe à l'écoute de mouseleave
lors du popover et s'il est déclenché, il appelle la fonction de congé d'origine afin qu'il puisse commencer à masquer le minuteur.
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 jeu de déclencheurs à hover
et ai donné le jeu de conteneurs au #element
, puis j'ai ajouté un emplacement de box
à right
.
Cela devrait être votre configuration:
$('#example').popover({
html: true,
trigger: 'hover',
container: '#example',
placement: 'right',
content: function () {
return '<div class="box"></div>';
}
});
et #example
css a besoin de position:relative;
vérifiez le jsfiddle ci-dessous:
https://jsfiddle.net/9qn6pw4p/1/
Ce violon a les 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. ainsi, lorsque vous déplacez votre souris sur la popover, elle reste toujours sur l'élément. Bootstrap 3.3.2 fonctionne bien avec cela. L’ancienne version peut avoir des problèmes d’animation, vous pouvez donc désactiver "animation: false"
C'est ce que j'ai fait avec bootstrap popover avec l'aide d'autres bits sur le net. 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. Le popover disparaîtra à la sortie du produit ($ this .pop) ou du popover. Timeout est utilisé où affichera le popover jusqu'à la sortie via 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 et qui semble bien fonctionner, tout en vous permettant également d’utiliser l’implémentation Bootstrap normale pour activer tous les popovers.
Violon original: https://jsfiddle.net/eXpressive/hfear592/
Porté à 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');
});
Simple :)
$('[data-toggle="popover"]').popover( { "container":"body", "trigger":"focus", "html":true });
$('[data-toggle="popover"]').mouseenter(function(){
$(this).trigger('focus');
});
Je conviens que le meilleur moyen consiste à utiliser celui donné par: David Chase , Cu Ly et d’autres que le moyen le plus simple de procéder consiste à utiliser la propriété container: $(this)
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 de texte à l'intérieur du popover. Je voulais juste enregistrer ça puisque j'ai passé pas mal de temps à me cogner la tête.
Vikas answer fonctionne parfaitement pour moi, j'ajoute ici un support pour le retard (afficher/masquer).
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);
});
Aussi s'il vous plaît faites 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 à cette popover ouverte, et à aucune autre (puisque maintenant, grâce au délai, plus d'un peut être ouvert en même temps)
La réponse choisie fonctionne mais échouera si le popover est initialisé avec la variable 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);
});
})
}
};
La modification est minimale en utilisant self.$tip
au lieu de traverser le DOM, en espérant que le popover sera toujours un frère de l'élément.
J'ai trouvé que la mouseleave
ne se déclencherait pas lorsque des événements étranges se produiraient, comme le changement de focus de la fenêtre, puis que l'utilisateur revient au navigateur. Dans ce cas, mouseleave
ne se déclenchera jamais tant que le curseur n’aura pas dépassé et ne quittera plus l’élément.
Cette solution proposée repose sur mouseenter
sur l'objet window
. Elle disparaît dès que 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 vont la 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");
}
});
});
$(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);
});
});
Même chose pour les info-bulles:
Pour moi, la solution suivante fonctionne parce qu’elle n’ajoute pas d’écouteurs d’événements à chaque 'mouseenter' et qu’il est possible de revenir en arrière sur l’élément d’info-bulle, ce qui la maintient active.
$ ->
$('.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
Ce 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);
}
)
Cette solution a bien fonctionné pour moi: (maintenant son 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);
});
}
Ceci est mon code pour afficher les info-bulles dynamiques avec délai et chargé par ajax.
$(window).on('load', function () {
generatePopovers();
$.fn.dataTable.tables({ visible: true, api: true }).on('draw.dt', function () {
generatePopovers();
});
});
$(document).ajaxStop(function () {
generatePopovers();
});
function generatePopovers() {
var popover = $('a[href*="../Something.aspx"]'); //locate the elements to popover
popover.each(function (index) {
var poplink = $(this);
if (poplink.attr("data-toggle") == null) {
console.log("RENDER POPOVER: " + poplink.attr('href'));
poplink.attr("data-toggle", "popover");
poplink.attr("data-html", "true");
poplink.attr("data-placement", "top");
poplink.attr("data-content", "Loading...");
poplink.popover({
animation: false,
html: true,
trigger: 'manual',
container: 'body',
placement: 'top'
}).on("mouseenter", function () {
var thispoplink = poplink;
setTimeout(function () {
if (thispoplink.is(":hover")) {
thispoplink.popover("show");
loadDynamicData(thispoplink); //load data by ajax if you want
$('body .popover').on("mouseleave", function () {
thispoplink.popover('hide');
});
}
}, 1000);
}).on("mouseleave", function () {
var thispoplink = poplink;
setTimeout(function () {
if (!$("body").find(".popover:hover").length) {
thispoplink.popover("hide");
}
}, 100);
});
}
});
function loadDynamicData(popover) {
var params = new Object();
params.somedata = popover.attr("href").split("somedata=")[1]; //obtain a parameter to send
params = JSON.stringify(params);
//check if the content is not seted
if (popover.attr("data-content") == "Loading...") {
$.ajax({
type: "POST",
url: "../Default.aspx/ObtainData",
data: params,
contentType: "application/json; charset=utf-8",
dataType: 'json',
success: function (data) {
console.log(JSON.parse(data.d));
var dato = JSON.parse(data.d);
if (dato != null) {
popover.attr("data-content",dato.something); // here you can set the data returned
if (popover.is(":hover")) {
popover.popover("show"); //use this for reload the view
}
}
},
failure: function (data) {
itShowError("- Error AJAX.<br>");
}
});
}
}