Comment puis-je vérifier si la souris est sur un élément en jQuery?
y a-t-il un moyen rapide et facile de faire cela à jQuery que je manque?
Je ne veux pas utiliser l'événement mouseover parce que je l'utilise déjà pour autre chose. J'ai juste besoin de savoir si la souris est au-dessus d'un élément à un moment donné.
j'aimerais faire quelque chose comme ça, si seulement il y avait une fonction" IsMouseOver":
function hideTip(oi) {
setTimeout(function() { if (!IsMouseOver(oi)) $(oi).fadeOut(); }, 100);
}
24 réponses
définit un délai sur le mouseout à fadeout et stocke la valeur de retour aux données dans l'objet. Puis onmouseover, annulez le délai s'il y a une valeur dans les données.
supprimer les données sur le rappel du fadeout.
il est en fait moins cher d'utiliser mouseenter/mouseleave parce qu'ils ne tirent pas pour le menu lorsque les enfants mouseover/mouseout feu.
ce code illustre ce que happytime harry et j'essaie de dire. Quand la souris entre, une infobulle sort, quand la souris sort elle fixe un délai pour qu'elle disparaisse. Si la souris entre dans le même élément avant que le retard ne soit déclenché, alors nous détruisons le déclencheur avant qu'il ne se déclenche en utilisant les données que nous avons stockées auparavant.
$("someelement").mouseenter(function(){
clearTimeout($(this).data('timeoutId'));
$(this).find(".tooltip").fadeIn("slow");
}).mouseleave(function(){
var someElement = $(this),
timeoutId = setTimeout(function(){
someElement.find(".tooltip").fadeOut("slow");
}, 650);
//set the timeoutId, allowing us to clear this trigger if the mouse comes back over
someElement.data('timeoutId', timeoutId);
});
Un, propre et élégant passez case:
if ($('#element:hover').length != 0) {
// do something ;)
}
AVERTISSEMENT: is(':hover')
est obsolète dans jquery 1.8+. Voir ce post pour une solution.
vous pouvez également utiliser cette réponse: https://stackoverflow.com/a/6035278/8843 pour tester si la souris est en stationnaire un élément:
$('#test').click(function() {
if ($('#hello').is(':hover')) {
alert('hello');
}
});
vous pouvez utiliser l'événement hover
de jQuery pour suivre manuellement:
$(...).hover(
function() { $.data(this, 'hover', true); },
function() { $.data(this, 'hover', false); }
).data('hover', false);
if ($(something).data('hover'))
//Hovered!
j'avais besoin de quelque chose exactement comme ceci (dans un environnement un peu plus complexe et la solution avec beaucoup de 'mouseenters' et 'mouseleaves' ne fonctionnait pas correctement) donc j'ai créé un petit plugin jquery qui ajoute la méthode ismouseover. Il a très bien fonctionné jusqu'à présent.
//jQuery ismouseover method
(function($){
$.mlp = {x:0,y:0}; // Mouse Last Position
function documentHandler(){
var $current = this === document ? $(this) : $(this).contents();
$current.mousemove(function(e){jQuery.mlp = {x:e.pageX,y:e.pageY}});
$current.find("iframe").load(documentHandler);
}
$(documentHandler);
$.fn.ismouseover = function(overThis) {
var result = false;
this.eq(0).each(function() {
var $current = $(this).is("iframe") ? $(this).contents().find("body") : $(this);
var offset = $current.offset();
result = offset.left<=$.mlp.x && offset.left + $current.outerWidth() > $.mlp.x &&
offset.top<=$.mlp.y && offset.top + $current.outerHeight() > $.mlp.y;
});
return result;
};
})(jQuery);
puis dans n'importe quel endroit du document vous l'appelez comme ceci et il retourne vrai ou faux:
$("#player").ismouseover()
Je l'ai testé sur IE7+, Chrome 1+ et Firefox 4 et est travail correctement.
en jQuery vous pouvez utiliser .is (': hover'), so
function IsMouseOver(oi)
{
return $(oi).is(':hover');
}
serait désormais le moyen le plus concis de fournir la fonction demandée dans le PO.
Note: ce qui précède ne fonctionne pas en IE8 ou moins
comme alternative moins succincte qui fonctionne dans IE8 (si je peux me fier au modus IE8 de IE9), et le fait sans déclencher $(...).hover(...)
partout, ni nécessite de connaître un sélecteur pour l'élément (auquel cas la réponse D'Ivo est plus facile):
function IsMouseOver(oi)
{
return oi.length &&
oi.parent()
.find(':hover')
.filter(function(s){return oi[0]==this})
.length > 0;
}
j'ai pris L'idée de SLaks et l'ai enveloppée dans une petite classe .
function HoverWatcher(selector){
this.hovering = false;
var self = this;
this.isHoveringOver = function() {
return self.hovering;
}
$(selector).hover(function() {
self.hovering = true;
}, function() {
self.hovering = false;
})
}
var box1Watcher = new HoverWatcher('#box1');
var box2Watcher = new HoverWatcher('#box2');
$('#container').click(function() {
alert("box1.hover = " + box1Watcher.isHoveringOver() +
", box2.hover = " + box2Watcher.isHoveringOver());
});
juste pour info pour les futurs découvreurs de ceci.
j'ai fait un plugin jQuery qui peut faire ceci et beaucoup plus. Dans mon plugin, pour obtenir tous les éléments que le curseur est actuellement en vol stationnaire, il suffit de faire ce qui suit:
$.cursor("isHover"); // will return jQ object of all elements the cursor is
// currently over & doesn't require timer
comme je l'ai mentionné, il a aussi beaucoup d'autres utilisations comme vous pouvez le voir dans le jsFiddle trouvé ici
comme je ne peux pas commenter, donc je vais écrire ceci comme une réponse!
s'il vous Plaît comprendre la différence entre le sélecteur css ":hover" et le hover événement!
": hover" est un sélecteur css et a été effectivement supprimé avec l'événement lorsqu'il est utilisé comme ce $("#elementId").is(":hover")
, mais dans ce sens, il a vraiment rien à voir avec l'événement jQuery hover.
si vous cochez $("#elementId:hover")
, l'élément ne sera sélectionné que lorsque vous souris. l'énoncé ci-dessus fonctionnera avec toutes les versions de jQuery comme votre sélection de cet élément avec la sélection CSS pure et légitime.
d'autre part, le vol stationnaire d'événement qui est
$("#elementId").hover(
function() {
doSomething();
}
);
est en effet déprécié comme jQuery 1.8 voici l'état du site de jQuery:
Lorsque le nom de l'événement "hover" est utilisé, l'événement sous-système convertit "mouseenter mouseleave" dans le cas de la chaîne. C'est gênant pour plusieurs raisons:
sémantique: planer n'est pas la même chose que la souris entrant et sortant un élément, il implique une certaine décélération ou un certain retard avant tir. Nom de l'événement: L'événement.type retourné par le gestionnaire est attaché pas en vol stationnaire, mais en mouseenter ou en mouseleave. Aucun autre événement n' ce. Coopter le nom "hover": il n'est pas possible de joindre événement avec le nom "hover" et le feu à l'aide .trigger ("hover"). Le docs déjà appeler ce nom "fortement déconseillé pour le nouveau code", je comme pour railler officiellement pour 1,8 et éventuellement le supprimer.
pourquoi ils ont supprimé l'usage est (": hover") n'est pas clair, mais oh bien, vous pouvez toujours l'utiliser comme ci-dessus et voici un petit hack pour l'utiliser encore.
(function ($) {
/**
* :hover selector was removed from jQuery 1.8+ and cannot be used with .is(":hover")
* but using it in this way it works as :hover is css selector!
*
**/
$.fn.isMouseOver = function() {
return $(this).parent().find($(this).selector + ":hover").length > 0;
};
})(jQuery);
Oh, et j' ne serait pas recomment le délai d'attente de la version que cette apporte son lot de complexité , l'utilisation de timeout fonctionnalità © s pour ce genre de choses s'il n'y a pas d'autre moyen et croyez-moi, dans 95% pourcentage de tous les cas il y a un autre moyen !
J'espère pouvoir aider quelques personnes là-bas.
Greetz Andy
merci à tous les deux. À un certain moment, j'ai dû renoncer à essayer de détecter si la souris était toujours au-dessus de l'élément. Je sais que c'est possible, mais il faudra peut-être trop de code pour l'accomplir.
ça m'a pris un peu de temps mais j'ai pris vos deux suggestions et j'ai trouvé quelque chose qui marcherait pour moi.
voici un exemple simplifié (mais fonctionnel):
$("[HoverHelp]").hover (
function () {
var HelpID = "#" + $(this).attr("HoverHelp");
$(HelpID).css("top", $(this).position().top + 25);
$(HelpID).css("left", $(this).position().left);
$(HelpID).attr("fadeout", "false");
$(HelpID).fadeIn();
},
function () {
var HelpID = "#" + $(this).attr("HoverHelp");
$(HelpID).attr("fadeout", "true");
setTimeout(function() { if ($(HelpID).attr("fadeout") == "true") $(HelpID).fadeOut(); }, 100);
}
);
et puis de faire ce travail sur un certain texte c'est tout ce que j'ai à faire:
<div id="tip_TextHelp" style="display: none;">This help text will show up on a mouseover, and fade away 100 milliseconds after a mouseout.</div>
This is a <span class="Help" HoverHelp="tip_TextHelp">mouse over</span> effect.
avec beaucoup de fancy CSS, cela permet quelques très belles mousee help tooltips. Au fait, j'ai eu besoin du délai dans la mouseout en raison de minuscules écarts entre les cases à cocher et le texte qui a été la cause de l'aide à clignoter que vous déplacez la souris à travers. Mais cela fonctionne comme un charme. J'ai aussi fait quelque chose de similaire pour les événements focus/flou.
je vois des temps morts utilisés pour cela beaucoup, mais dans le contexte d'un événement, ne pouvez-vous pas regarder les coordonnées, comme ceci?:
function areXYInside(e){
var w=e.target.offsetWidth;
var h=e.target.offsetHeight;
var x=e.offsetX;
var y=e.offsetY;
return !(x<0 || x>=w || y<0 || y>=h);
}
selon le contexte, vous devrez peut-être vous assurer (ceci==E. target) avant d'appeler areXYInside (e).
fyi - je regarde l'utilisation de cette approche à l'intérieur d'un gestionnaire de dragLeave, afin de confirmer que l'événement de dragLeave n'a pas été déclenché en entrant dans un élément enfant. Si tu ne vérifies pas que tu es toujours à l'intérieur de l'élément parent, vous pourriez par erreur prendre des mesures qui ne sont destinées qu'au moment où vous quittez vraiment le parent.
EDIT: c'est une bonne idée, mais ça ne marche pas assez régulièrement. Peut-être avec quelques petites modifications.
vous pouvez tester avec jQuery
si un enfant div a une certaine classe. Ensuite, en appliquant cette classe lorsque vous passez la souris sur une certaine div, vous pouvez tester si votre souris est dessus, même si vous passez la souris sur un élément différent sur la page beaucoup moins de code de cette façon. J'ai utilisé ceci parce que j'avais des espaces entre les divs dans un pop-up, et je voulais seulement fermer le pop-up quand j'ai quitté le pop-up, pas quand je déplaçais ma souris sur les espaces dans le pop-up. J'ai donc appelé un la fonction mouseover sur la Div de contenu (qui le pop up était plus), mais il ne déclencherait la fonction close que lorsque je mouse-au-dessus de la div de contenu, et était à l'extérieur du pop up!
$(".pop-up").mouseover(function(e) { $(this).addClass("over"); }); $(".pop-up").mouseout(function(e) { $(this).removeClass("over"); }); $("#mainContent").mouseover(function(e){ if (!$(".expanded").hasClass("over")) { Drupal.dhtmlMenu.toggleMenu($(".expanded")); } });
ce serait la façon la plus facile de le faire!
function(oi)
{
if(!$(oi).is(':hover')){$(oi).fadeOut(100);}
}
Voici une technique qui ne s'appuie pas sur jquery et utilise le DOM natif matches
API . Il utilise des préfixes de fournisseur pour soutenir les navigateurs remontant à IE9. Voir caniuse.com pour plus de détails.
créer D'abord la fonction matchesSelector, comme suit:
var matchesSelector = (function(ElementPrototype) {
var fn = ElementPrototype.matches ||
ElementPrototype.webkitMatchesSelector ||
ElementPrototype.mozMatchesSelector ||
ElementPrototype.msMatchesSelector;
return function(element, selector) {
return fn.call(element, selector);
};
})(Element.prototype);
puis, pour détecter le vol stationnaire:
var mouseIsOver = matchesSelector(element, ':hover');
j'ai répondu à cela dans une autre question, avec tous les détails dont vous pourriez avoir besoin:
Détecter SI planant au-dessus de l'élément avec jQuery (a 99 upvotes au moment de la rédaction)
en gros, vous pouvez faire quelque chose comme:
var ishovered = oi.is(":hover");
Cela ne fonctionne que si oi
est un objet jQuery contenant un seul élément. S'il y a plusieurs éléments appariés, vous devez appliquer à chaque élément, pour exemple:
var hoveredItem = !!$('ol>li').filter(function() { return $(this).is(":hover"); });
// not .filter(':hover'), as we can't apply :hover on multiple elements
cela a été testé à partir de jQuery 1.7.
Étendre sur ce que "Happytime harry" dit, assurez-vous d'utiliser .la fonction jQuery de data () pour stocker l'id de timeout. Ceci est pour que vous puissiez récupérer l'id de timeout très facilement lorsque le 'mouseenter' est déclenché sur ce même élément plus tard, vous permettant d'éliminer le déclencheur pour que votre tooltip disparaisse.
vous pouvez utiliser les événements mouseenter et mouseleave de jQuery. Vous pouvez définir un indicateur lorsque la souris entre dans la zone désirée et annuler le drapeau lorsqu'il quitte la zone.
j'ai combiné des idées de ce sujet et est venu avec ceci, qui est utile pour montrer / cacher un sous-menu:
$("#menu_item_a").mouseenter(function(){
clearTimeout($(this).data('timeoutId'));
$("#submenu_a").fadeIn("fast");
}).mouseleave(function(){
var menu_item = $(this);
var timeoutId = setTimeout(function(){
if($('#submenu_a').is(':hover'))
{
clearTimeout(menu_item.data('timeoutId'));
}
else
{
$("#submenu_a").fadeOut("fast");
}
}, 650);
menu_item.data('timeoutId', timeoutId);
});
$("#submenu_a").mouseleave(function(){
$(this).fadeOut("fast");
});
Semble fonctionner pour moi. Espérons que cela aide quelqu'un.
EDIT: Maintenant, la réalisation de cette approche ne fonctionne pas correctement dans internet explorer.
Je ne pouvais utiliser aucune des suggestions ci-dessus.
Pourquoi je préfère ma solution?
Cette méthode vérifie si la souris est sur un élément à n'importe quel moment choisi par vous .
Mouseenter et :hover sont cool, mais mouseenter ne se déclenche que si vous déplacez la souris, et non pas lorsque l'élément se déplace sous la souris.
:hover est assez doux mais ... IE
alors je fais ceci:
N ° 1. store souris x, Y position à chaque fois qu'il est déplacé quand vous avez besoin de,
No 2. vérifier si la souris est sur l'un des éléments qui correspondent à la requête faire des choses ... comme déclencher un événement mouseenter
// define mouse x, y variables so they are traced all the time
var mx = 0; // mouse X position
var my = 0; // mouse Y position
// update mouse x, y coordinates every time user moves the mouse
$(document).mousemove(function(e){
mx = e.pageX;
my = e.pageY;
});
// check is mouse is over an element at any time You need (wrap it in function if You need to)
$("#my_element").each(function(){
boxX = $(this).offset().left;
boxY = $(this).offset().top;
boxW = $(this).innerWidth();
boxH = $(this).innerHeight();
if ((boxX <= mx) &&
(boxX + 1000 >= mx) &&
(boxY <= my) &&
(boxY + boxH >= my))
{
// mouse is over it so you can for example trigger a mouseenter event
$(this).trigger("mouseenter");
}
});
juste une note au sujet de la réponse populaire et utile D'Arthur Goldsmith ci-dessus: si vous déplacez votre souris d'un élément à un autre dans IE (au moins JUSQU'à ce que IE 9) Vous pouvez avoir de la difficulté à ce que cela fonctionne correctement si le nouvel élément a un fond transparent (qui serait par défaut). Ma solution était de donner au nouvel élément une image de fond transparente.
Voici une fonction qui vous aide à vérifier si la souris est dans un élément ou non. La seule chose que vous devez faire est d'appeler la fonction où vous pouvez avoir une souris vivante associée EventObject. quelque chose comme ceci:
$("body").mousemove(function(event){
element_mouse_is_inside($("#mycontainer", event, true, {});
});
vous pouvez voir le code source ici dans github ou au bas du post:
https://github.com/mostafatalebi/ElementsLocator/blob/master/elements_locator.jquery.js
function element_mouse_is_inside (elementToBeChecked, mouseEvent, with_margin, offset_object)
{
if(!with_margin)
{
with_margin = false;
}
if(typeof offset_object !== 'object')
{
offset_object = {};
}
var elm_offset = elementToBeChecked.offset();
var element_width = elementToBeChecked.width();
element_width += parseInt(elementToBeChecked.css("padding-left").replace("px", ""));
element_width += parseInt(elementToBeChecked.css("padding-right").replace("px", ""));
var element_height = elementToBeChecked.height();
element_height += parseInt(elementToBeChecked.css("padding-top").replace("px", ""));
element_height += parseInt(elementToBeChecked.css("padding-bottom").replace("px", ""));
if( with_margin)
{
element_width += parseInt(elementToBeChecked.css("margin-left").replace("px", ""));
element_width += parseInt(elementToBeChecked.css("margin-right").replace("px", ""));
element_height += parseInt(elementToBeChecked.css("margin-top").replace("px", ""));
element_height += parseInt(elementToBeChecked.css("margin-bottom").replace("px", ""));
}
elm_offset.rightBorder = elm_offset.left+element_width;
elm_offset.bottomBorder = elm_offset.top+element_height;
if(offset_object.hasOwnProperty("top"))
{
elm_offset.top += parseInt(offset_object.top);
}
if(offset_object.hasOwnProperty("left"))
{
elm_offset.left += parseInt(offset_object.left);
}
if(offset_object.hasOwnProperty("bottom"))
{
elm_offset.bottomBorder += parseInt(offset_object.bottom);
}
if(offset_object.hasOwnProperty("right"))
{
elm_offset.rightBorder += parseInt(offset_object.right);
}
var mouseX = mouseEvent.pageX;
var mouseY = mouseEvent.pageY;
if( (mouseX > elm_offset.left && mouseX < elm_offset.rightBorder)
&& (mouseY > elm_offset.top && mouseY < elm_offset.bottomBorder) )
{
return true;
}
else
{
return false;
}
}
vous pouvez utiliser is(':visible');
en jquery
Et pour $('.élément:hover') en Jquery.
c'est un code htm snnipet:
<li class="item-109 deeper parent">
<a class="root" href="/Comsopolis/index.php/matiers"><span>Matiers</span></a>
<ul>
<li class="item-110 noAff">
<a class=" item sousMenu" href="/Comsopolis/index.php/matiers/tsdi">
<span>Tsdi</span>
</a>
</li>
<li class="item-111 noAff">
<a class="item" href="/Comsopolis/index.php/matiers/reseaux">
<span>Réseaux</span>
</a>
</li>
</ul>
</li>
et voici le Code JS:
$('.menutop > li').hover(function() {//,.menutop li ul
$(this).find('ul').show('fast');
},function() {
if($(this).find('ul').is(':hover'))
$(this).hide('fast');
});
$('.root + ul').mouseleave(function() {
if($(this).is(':visible'))
$(this).hide('fast');
});
ce de quoi je parlais :)