是否有一个快速和简单的方法来做到这一点在jQuery,我错过了?
我不想使用鼠标悬停事件,因为我已经将它用于其他事情。我只需要知道鼠标在给定时刻是否在某个元素上。
我想做一些这样的事情,如果有一个“IsMouseOver”函数:
function hideTip(oi) {
setTimeout(function() { if (!IsMouseOver(oi)) $(oi).fadeOut(); }, 100);
}
是否有一个快速和简单的方法来做到这一点在jQuery,我错过了?
我不想使用鼠标悬停事件,因为我已经将它用于其他事情。我只需要知道鼠标在给定时刻是否在某个元素上。
我想做一些这样的事情,如果有一个“IsMouseOver”函数:
function hideTip(oi) {
setTimeout(function() { if (!IsMouseOver(oi)) $(oi).fadeOut(); }, 100);
}
当前回答
在鼠标退出时设置超时以淡出并将返回值存储为对象中的数据。然后onmouseover,如果数据中有值,取消超时。
删除淡出的回调数据。
使用mouseenter/mouseleave实际上成本更低,因为当child鼠标悬停/鼠标退出触发时,它们不会触发菜单。
其他回答
谢谢你们俩。在某种程度上,我不得不放弃尝试检测鼠标是否仍然停留在元素上。我知道这是可能的,但可能需要太多的代码来实现。
我花了一点时间,但我接受了你们的建议,并想出了适合我的办法。
下面是一个简单的例子:
$("[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,这允许一些非常漂亮的鼠标悬停帮助工具提示。顺便说一下,我需要在鼠标退出时延迟,因为复选框和文本之间的微小间隙导致当你移动鼠标时帮助会闪烁。但这就像一个魔法。我也为焦点/模糊事件做了类似的事情。
我需要的东西正是这样的(在一个更复杂的环境和解决方案有很多'mouseenter '和'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,并使用本机DOM匹配API。它使用厂商前缀支持回到IE9的浏览器。详情请参阅caniuse.com上的matchesselector。
首先创建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');
我结合了这个主题的想法,想出了这个,这对于显示/隐藏子菜单很有用:
$("#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中不能正确工作。
下面是一个函数,它可以帮助你检查鼠标是否在元素中。惟一需要做的是调用函数,在这里可以有一个与鼠标相关的活动eventtobject。就像这样:
$("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;
}
}