如何检查鼠标是否在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'); });
这是我在说什么:)