如何检查鼠标是否在jQuery中的元素?

有没有一个快速和简单的方法来做到这一点在jQuery中,我失踪了?

我不想使用mouseover事件,因为我已经使用它来做其他事情了。 我只需要知道在给定时刻鼠标是否在某个元素上。

我想要做这样的事情,如果只有一个“IsMouseOver”函数:

function hideTip(oi) { setTimeout(function() { if (!IsMouseOver(oi)) $(oi).fadeOut(); }, 100); } 

在mouseout上设置超时以淡出,并将返回值存储到对象中的数据。 然后onmouseover,如果数据中有一个值,取消超时。

删除淡出的callback数据。

使用mouseenter / mouseleave实际上是比较便宜的,因为当小孩mouseover / mouseout被触发时,它们不会为菜单而激发。

这段代码说明了哈利和我想说的是什么。 当鼠标进入时,一个工具提示出来,当鼠标离开时,它设置一个延迟,消失。 如果鼠标在延迟被触发之前进入相同的元素,那么我们使用之前存储的数据在触发之前就销毁触发器。

 $("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); }); 

清洁和优雅的hover检查:

 if ($('#element:hover').length != 0) { // do something ;) } 

警告: is(':hover')在jquery 1.8 +中被弃用。 看到这个职位的解决scheme。

您也可以使用这个答案: https : //stackoverflow.com/a/6035278/8843来testing鼠标是否hover一个元素:

 $('#test').click(function() { if ($('#hello').is(':hover')) { alert('hello'); } }); 

您可以使用jQuery的hover事件手动跟踪:

 $(...).hover( function() { $.data(this, 'hover', true); }, function() { $.data(this, 'hover', false); } ).data('hover', false); if ($(something).data('hover')) //Hovered! 

我需要的东西完全是这样的(在一个更复杂的环境中,有很多'mouseenters'和'mouseleaves'的解决scheme工作不正常),所以我创build了一个小jQuery插件,添加方法ismouseover。 到目前为止它工作得很好。

 //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); 

然后在文件的任何地方哟叫这样,它返回true或false:

 $("#player").ismouseover() 

我在IE7 +,Chrome 1 +和Firefox 4上进行了testing,工作正常。

在jQuery中你可以使用.is(':hover'),所以

 function IsMouseOver(oi) { return $(oi).is(':hover'); } 

现在将是提供OP中所请求的function的最简洁的方式。

注:以上在IE8或更低版本中不起作用

作为不太简洁的替代scheme,在IE8中工作(如果我可以信任IE9的IE8模式),并且不需要触发$(...).hover(...)到处,也不需要知道元素的select器(在这种情况下,Ivo的答案更容易):

 function IsMouseOver(oi) { return oi.length && oi.parent() .find(':hover') .filter(function(s){return oi[0]==this}) .length > 0; } 

我把SLaks的想法包装在一个小课堂里 。

 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()); }); 

只是FYI未来发现这个。

我做了一个jQuery插件,可以做到这一点,还有更多。 在我的插件中,为了获得所有的元素,光标当前被盘旋,只需执行以下操作:

 $.cursor("isHover"); // will return jQ object of all elements the cursor is // currently over & doesn't require timer 

正如我提到的,它也有很多其他用途,你可以看到在

jsFiddle在这里find

由于我不能评论,所以我会写这个答案!

请理解cssselect器“:hover”与hover事件的区别!

“:hover”是一个cssselect器,当使用像这样$("#elementId").is(":hover")时候确实被删除了,但是这意味着它和jQuery事件hover没有任何关系。

如果您编码$("#elementId:hover") ,则只有在鼠标hover的情况下才会选中该元素。 上面的语句将适用于所有的jQuery版本,因为你select纯粹和合法的CSSselect这个元素。

另一方面,事件hover是

 $("#elementId").hover( function() { doSomething(); } ); 

jQuery 1.8在这里从jQuery网站的状态确实被贬低了:

当使用事件名称“hover”时,事件子系统将其转换为事件string中的“mouseenter mouseleave”。 这是令人讨厌的几个原因:

语义:鼠标hover与鼠标进入和离开某个元素不一样,这意味着在开始之前会有一定程度的减速或延迟。 事件名称:附加处理程序返回的event.type不是hover的,而是mouseenter或mouseleave。 没有其他事件做到这一点。 select“hover”名称:不能附加名称为“hover”的事件并使用.trigger(“hover”)将其激活。 文档已经叫这个名字“强烈不鼓励新的代码”,我想正式弃用它,并最终删除它。

为什么他们删除的用法是(“:hover”)还不清楚,但是好吧,你仍然可以像上面一样使用它,这里还是有点用处。

 (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); 

哦,我不会推荐超时版本,因为这会带来很多复杂性 ,如果没有别的方法并且相信我,使用超时function来处理这种东西, 95%的情况下都有另一种方式

希望我可以帮助一些人在那里。

Greetz Andy

感谢你们俩。 在某个时候,我不得不放弃,试图检测鼠标是否仍然在这个元素上。 我知道这是可能的,但可能需要太多的代码来完成。

我花了一段时间,但我采取了你的两个build议,并提出了一些适合我的东西。

这是一个简化的(但function)的例子:

 $("[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); } ); 

然后,在一些文本上做这个工作,这是我所要做的:

 <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. 

随着很多花哨的CSS,这允许一些非常好的鼠标hover帮助工具提示。 顺便说一下,由于checkbox和文本之间的微小间隙导致帮助在移动鼠标时发生闪烁,因此我需要在鼠标hover的时候进行延迟。 但是,这就像一个魅力。 我也做了类似的焦点/模糊事件。

我看到很多这样的超时,但是在一个事件的背景下,你不能看这样的坐标吗?

 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); } 

根据上下文,您可能需要确保(this == e.target)在调用areXYInside(e)之前。

fyi-我正在使用dragLeave处理程序中使用此方法,以确认dragLeave事件不是通过进入一个子元素触发。 如果你不确定你是否还在父母的内部,你可能会错误地采取那些只有在你真的离开父母的时候采取的行动。

编辑:这是一个不错的主意,但不够一致的工作。 也许有一些小的调整。

如果任何子div有一个特定的类,你可以用jQuery来testing。 然后,当您将鼠标hover在某个div上时,通过应用该类,即使将鼠标hover在页面上的其他元素上,您也可以testing鼠标是否在其上。 我之所以用这个,是因为我在popup窗口中的div之间有空格,而我只想在popup窗口时closurespopup窗口,而不是在popup的空格处移动鼠标。 所以我在内容div上调用了一个鼠标hoverfunction(当popup窗口结束时),但是当我对内容div进行掩盖时,它只会触发closuresfunction,并且不在popup窗口中!


 $( “popup”)。鼠标指向(函数(E)
     {
     $(本).addClass( “超速”);
     });

 $( “popup”)。鼠标移开(function(E)
     {
     $(本).removeClass( “超速”);
     });


 $( “#searchMaincontent”)。鼠标指向(函数(E){
             if(!$(“。expanded”)。hasClass(“over”)){
             Drupal.dhtmlMenu.toggleMenu($() “扩大了。”);
         }
     });

这将是最简单的方法!

  function(oi) { if(!$(oi).is(':hover')){$(oi).fadeOut(100);} } 

我在另一个问题上回答了这个问题,你可能需要所有的细节:

使用jQuery检测IFhover在元素上 (写作时有99个upvotes)

基本上,你可以做这样的事情:

 var ishovered = oi.is(":hover"); 

这只适用于oi是一个包含单个元素的jQuery对象。 如果有多个元素匹配,则需要应用到每个元素,例如:

 var hoveredItem = !!$('ol>li').filter(function() { return $(this).is(":hover"); }); // not .filter(':hover'), as we can't apply :hover on multiple elements 

这是从jQuery 1.7开始testing的。

这是一种不依赖于jquery并使用本地DOM matches API的技术 。 它使用供应商前缀来支持浏览器返回到IE9。 有关完整的详细信息,请参阅caniuse.com上的matchesselector 。

首先创buildmatchesSelector函数,如下所示:

 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); 

然后,检测hover:

 var mouseIsOver = matchesSelector(element, ':hover'); 

扩展“快乐时光哈利”说,一定要使用.data()jquery函数来存储超时ID。 这样,当稍后在同一个元素上触发“mouseenter”时,您可以非常轻松地检索超时ID,从而消除工具提示消失的触发器。

你可以使用jQuery的mouseenter和mouseleave事件。 您可以在鼠标进入所需区域时设置一个标志,并在离开该区域时取消设置标志。

我结合了这个主题的想法,并提出这个,这是显示/隐藏子菜单有用:

 $("#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"); }); 

似乎为我工作。 希望这有助于某人。

编辑:现在实现这种方法是不正确的在IE浏览器。

我无法使用上面的任何build议。
我为什么喜欢我的解决scheme
这个方法检查鼠标在你select的任何时候是否在一个元素上。
Mouseenter:hover是很酷的,但是mouseenter只有在你移动鼠标时触发,而不是在元素在鼠标下面移动的时候触发。
:hover是非常甜蜜的,但… IE浏览器

所以我这样做:

没有1.存储鼠标x,y的位置,每当它需要移动时,
否2.检查鼠标是否与查询匹配的任何元素相同…就像触发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"); } }); 

上面的stream行和有用的亚瑟戈德史密斯答案只是一个笔记:如果你在IE中移动你的鼠标从一个元素到另一个(至less直到IE 9),你可能会遇到一些麻烦,如果新元素有一个正确的工作透明的背景(这是默认情况下)。 我的解决方法是给新元素一个透明的背景图像。

 $(document).hover(function(e) { alert(e.type === 'mouseenter' ? 'enter' : 'leave'); }); 

小提琴

这里有一个函数可以帮助你检查鼠标是否在元素内部。 你应该做的唯一事情就是调用你可以有一个活的鼠标相关的EventObject的函数。 像这样的东西:

 $("body").mousemove(function(event){ element_mouse_is_inside($("#mycontainer", event, true, {}); }); 

您可以在github或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; } } 

你可以使用is(':visible'); 在jQuery和$('。item:hover')它也在jquery中工作。

这是一个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> 

这是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'); }); 

这是我在说什么:)