有没有一种快速简便的方法可以在我缺少的jQuery中做到这一点?
我不想使用mouseover事件,因为我已经将它用于其他用途。我只需要知道鼠标在给定时刻是否位于某个元素上。
如果只有一个“ IsMouseOver”功能,我想做这样的事情:
function hideTip(oi) {
setTimeout(function() { if (!IsMouseOver(oi)) $(oi).fadeOut(); }, 100);
}
有没有一种快速简便的方法可以在我缺少的jQuery中做到这一点?
我不想使用mouseover事件,因为我已经将它用于其他用途。我只需要知道鼠标在给定时刻是否位于某个元素上。
如果只有一个“ IsMouseOver”功能,我想做这样的事情:
function hideTip(oi) {
setTimeout(function() { if (!IsMouseOver(oi)) $(oi).fadeOut(); }, 100);
}
Answers:
将鼠标悬停设置为超时以淡出并将返回值存储到对象中的数据。然后onmouseover,如果数据中有值,则取消超时。
删除淡出回调的数据。
实际上,使用mouseenter / mouseleave较便宜,因为当孩子将鼠标悬停/鼠标移开时,它们不会触发菜单。
这段代码说明了我和哈利法特(harrytime)哈里到底在说什么。当鼠标进入时,会出现一个工具提示,当鼠标离开时,它会设置一个消失的延迟。如果在延迟触发之前鼠标进入相同的元素,那么我们将使用之前存储的数据在触发器触发之前销毁它。
$("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);
});
干净优雅的悬停检查:
if ($('#element:hover').length != 0) {
// do something ;)
}
警告:is(':hover')
在jQuery 1.8+中已弃用。请参阅此帖子以获取解决方案。
您还可以使用以下答案:https : //stackoverflow.com/a/6035278/8843来测试鼠标是否悬停在元素上:
$('#test').click(function() {
if ($('#hello').is(':hover')) {
alert('hello');
}
});
document.querySelectorAll(':hover')
您可以使用jQuery的hover
事件来手动跟踪:
$(...).hover(
function() { $.data(this, 'hover', true); },
function() { $.data(this, 'hover', false); }
).data('hover', false);
if ($(something).data('hover'))
//Hovered!
$.data
不涉及字符串操作。
我确实需要一些东西(在稍微复杂的环境中,并且有很多“ mouseenters”和“ mouseleaves”的解决方案无法正常工作),所以我创建了一个小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上进行了测试,并且可以正常工作。
在jQuery中,您可以使用.is(':hover'),因此
function IsMouseOver(oi)
{
return $(oi).is(':hover');
}
现在将是提供OP中所要求功能的最简洁方法。
注意:以上在IE8或更低版本中不起作用
作为一种不太简洁的替代方法,它可以在IE8中使用(如果我可以信任IE9的IE8方式),并且无需触发$(...).hover(...)
所有操作,也不需要知道该元素的选择器(在这种情况下,Ivo的回答会更容易):
function IsMouseOver(oi)
{
return oi.length &&
oi.parent()
.find(':hover')
.filter(function(s){return oi[0]==this})
.length > 0;
}
$(':hover')
确实可以在IE8中使用。这是有效的CSS2伪选择器,因此应该可以使用。
我接受了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());
});
仅供参考,以供将来的发现者使用。
我做了一个jQuery插件,可以做到这一点以及更多。在我的插件中,要获取光标当前悬停的所有元素,只需执行以下操作:
$.cursor("isHover"); // will return jQ object of all elements the cursor is
// currently over & doesn't require timer
由于无法发表评论,因此我将其作为答案!
请了解CSS选择器“:hover”和悬停事件之间的区别!
“:hover”是一个css选择器,当像这样使用时,确实与事件一起被删除 $("#elementId").is(":hover")
,但这意味着它实际上与jQuery事件悬停无关。
如果你编码 $("#elementId:hover")
,则仅当您将鼠标悬停时才选择该元素。上面的语句将与所有jQuery版本一起使用,因为您可以通过纯净合法的CSS选择选择此元素。
另一方面,事件悬停是
$("#elementId").hover(
function() {
doSomething();
}
);
确实已弃用jQuery 1.8,这里是jQuery网站的状态:
当使用事件名称“ hover”时,事件子系统会将其转换为事件字符串中的“ mouseenter mouseleave”。这很烦人,原因有几个:
语义:悬停与鼠标进入和离开元素不同,它表示发射前一定程度的减速或延迟。事件名称:附加处理程序返回的event.type不是悬停的,而是mouseenter或mouseleave。没有其他事件可以这样做。选择“ hover”名称:无法附加名称为“ hover”的事件并使用.trigger(“ hover”)触发它。文档已经将该名称称为“强烈建议不要使用新代码”,我想正式将其弃用1.8,最后将其删除。
为什么他们删除了用法is(“: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);
哦,我不会推荐超时版本,因为这会带来很多复杂性,如果没有其他方法可以相信我,请在这种情况下使用超时功能,在所有情况的95%中,还有另一种方法!
希望我能帮助几个人。
格蕾兹·安迪
感谢你们俩。在某些时候,我不得不放弃尝试检测鼠标是否仍在元素上方。我知道这是可能的,但可能需要太多代码才能完成。
我花了一段时间,但我接受了您的两个建议,并提出了一些对我有用的方法。
这是一个简化(但实用)的示例:
$("[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,这提供了一些非常不错的鼠标悬停帮助工具提示。顺便说一句,由于复选框和文本之间的微小间隙导致移动帮助时闪烁的帮助,因此我需要延迟鼠标输出。但这就像一种魅力。对于焦点/模糊事件,我也做了类似的操作。
我看到超时经常用于此目的,但是在事件的背景下,您不能像这样查看坐标吗?
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);
}
根据上下文,您可能需要在调用areXYInside(e)之前确保(this == e.target)。
fyi-我正在研究在dragLeave处理程序中使用此方法,以确认dragLeave事件不是由进入子元素触发的。如果您不以某种方式检查自己是否仍在父元素内,则可能会错误地采取仅当您真正离开父元素时才执行的操作。
编辑:这是一个不错的主意,但不能始终如一地工作。也许有一些小的调整。
您可以测试jQuery
是否有任何子div具有特定的类。然后,通过在鼠标移出某个div时应用该类,即使您将鼠标悬停在页面上的其他元素上,也可以测试鼠标是否位于其上,从而用更少的代码编写代码。我之所以使用它,是因为在弹出窗口中的div之间有空格,并且我只想在移出弹出窗口时关闭弹出窗口,而不是在将鼠标移到弹出窗口中的空格上时关闭弹出窗口。因此,我在内容div上调用了mouseover函数(弹出窗口结束了),但是只有当我将鼠标悬停在内容div上且AND不在弹出窗口之外时,它才会触发关闭函数!
$(“。pop-up”)。mouseover(function(e) { $(this).addClass(“ over”); }); $(“。pop-up”)。mouseout(function(e) { $(this).removeClass(“ over”); }); $(“#mainContent”)。mouseover(function(e){ 如果(!$(“。expanded”)。hasClass(“ over”)){ Drupal.dhtmlMenu.toggleMenu($(“。expanded”));; } });
这是一种不依赖jquery并使用本机DOM matches
API的技术。它使用供应商前缀来支持可追溯到IE9的浏览器。有关完整详细信息,请参见caniuse.com上的matchsselector。
首先创建matchesSelector函数,如下所示:
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);
然后,检测悬停:
var mouseIsOver = matchesSelector(element, ':hover');
我已经在另一个问题中回答了这个问题,其中可能包含您需要的所有详细信息:
使用jQuery检测IF悬停在元素上(在撰写本文时已获得99票赞成)
基本上,您可以执行以下操作:
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开始对此进行了测试。
这是一个可以帮助您检查鼠标是否在元素内的功能。您唯一要做的就是调用该函数,在该函数中可以有一个与鼠标实时关联的EventObject。像这样的东西:
$("body").mousemove(function(event){
element_mouse_is_inside($("#mycontainer", event, true, {});
});
您可以在github或帖子底部看到源代码:
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;
}
}
您可以使用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中正常工作。
我无法使用以上任何建议。
为什么我更喜欢我的解决方案?
此方法在您选择的任何时间检查鼠标是否在元素上。
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");
}
});
您可以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');
});
这就是我在说的:)