纯 javascript 检查是否有悬浮(不设置 mouseover/out)

我见过这样的 jQuery 语法:

if($(element).is(':hover')) { do something}

因为我没有使用 jQuery,所以我在寻找用纯 javascript 实现这一点的最佳方法。

我知道我可以保留一个全局变量并使用 mouseovermouseout设置/取消它,但是我想知道是否有一些方法可以通过 DOM 检查元素的本机属性?也许是这样的:

if(element.style.className.hovered === true) {do something}

此外,它必须是跨浏览器兼容的。

97929 次浏览

首先,你需要跟踪哪些元素悬浮在上面:

(function() {
var matchfunc = null, prefixes = ["","ms","moz","webkit","o"], i, m;
for(i=0; i<prefixes.length; i++) {
m = prefixes[i]+(prefixes[i] ? "Matches" : "matches");
if( document.documentElement[m]) {matchfunc = m; break;}
m += "Selector";
if( document.documentElement[m]) {matchfunc = m; break;}
}
if( matchfunc) window.isHover = function(elem) {return elem[matchfunc](":hover");};
else {
window.onmouseover = function(e) {
e = e || window.event;
var t = e.srcElement || e.target;
while(t) {
t.hovering = true;
t = t.parentNode;
}
};
window.onmouseout = function(e) {
e = e || window.event;
var t = e.srcElement || e.target;
while(t) {
t.hovering = false;
t = t.parentNode;
}
};
window.isHover = function(elem) {return elem.hovering;};
}
})();

我想到一种检查元素是否悬停的方法是在 css :hover中设置一个未使用的属性,然后检查该属性是否存在于 javascript 中。它不是一个适当的解决方案,因为它没有利用本地悬停属性,但它是最接近和最小的解决方案,我可以想到。

<html>
<head>
<style type="text/css">
#hover_el
{
border: 0px solid blue;
height: 100px;
width: 100px;
background-color: blue;
}
#hover_el:hover
{
border: 0px dashed blue;
}
</style>
<script type='text/javascript'>
window.onload = function() {check_for_hover()};
function check_for_hover() {
var hover_element = document.getElementById('hover_el');
var hover_status = (getStyle(hover_element, 'border-style') === 'dashed') ? true : false;
document.getElementById('display').innerHTML = 'you are' + (hover_status ? '' : ' not') + ' hovering';
setTimeout(check_for_hover, 1000);
};
function getStyle(oElm, strCssRule) {
var strValue = "";
if(document.defaultView && document.defaultView.getComputedStyle) {
strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
}
else if(oElm.currentStyle) {
strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1) {
return p1.toUpperCase();
});
strValue = oElm.currentStyle[strCssRule];
}
return strValue;
};
</script>
</head>
<body>
<div id='hover_el'>hover here</div>
<div id='display'></div>
</body>
</html>

(功能 getStyle感谢 JavaScript 获取样式)

如果有人能想到一个更好的 css 属性作为一个标志使用比 solid/dashed请让我知道。最好的财产将是一个很少使用,不能继承。

编辑: CSS 变量可能是更好的用来检查这一点。

const fps = 60;


setInterval(function() {
if(getComputedStyle(document.getElementById('my-div')).getPropertyValue('--hovered') == 1) {
document.getElementById('result').innerHTML = 'Yes';
} else {
document.getElementById('result').innerHTML = 'No';
};
}, 1000 / fps);
#my-div {
--hovered:0;
color: black;
}


#my-div:hover {
--hovered:1;
color: red;
}
<!DOCTYPE html>
<html>
<head>
<title>Detect if div is hovered with JS, using CSS variables</title>
</head>
<body>
<div id="my-div">Am I hovered?</div>
<div id="result"></div>
</body>
</html>

你可以使用 QuerySelector对于 IE > = 8:

const isHover = e => e.parentElement.querySelector(':hover') === e;


const myDiv = document.getElementById('mydiv');
document.addEventListener('mousemove', function checkHover() {
const hovered = isHover(myDiv);
if (hovered !== checkHover.hovered) {
console.log(hovered ? 'hovered' : 'not hovered');
checkHover.hovered = hovered;
}
});
.whyToCheckMe {position: absolute;left: 100px;top: 50px;}
<div id="mydiv">HoverMe
<div class="whyToCheckMe">Do I need to be checked too?</div>
</div>

我认为这是好的@Kolink 回答。

简单地使用 element.matches(':hover')对我来说似乎工作得很好,你也可以为老的浏览器使用一个全面的填充: https://developer.mozilla.org/en-US/docs/Web/API/Element/matches

可以将 if语句与 querySelector语句一起使用。如果将“ : hover”添加到选择器的末尾,那么只有当元素悬停时,它才会返回该元素。这意味着您可以测试它是否返回 null。它类似于上面的 element.matches(":hover)解决方案,但是我在这个版本中获得了更多的成功。

这里有一个例子:

if (document.querySelector("body > p:hover") != null) {
console.log("hovered");
}

您可以将其放在一个间隔中,以便在每次悬停时运行代码:

setInterval(() => {
if (document.querySelector("body > p:hover") != null) {
console.log("hovered");
}
}, 10);