【问题标题】:pure javascript to check if something has hover (without setting on mouseover/out)纯 javascript 检查是否有悬停(不设置鼠标悬停/移出)
【发布时间】:2013-01-25 13:10:13
【问题描述】:

我见过这个 jQuery 语法:

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

由于我没有使用 jQuery,我正在寻找用纯 javascript 执行此操作的最佳方法。

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

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

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

【问题讨论】:

  • 我花了 20 分钟寻找找到这种状态的方法。我怀疑您可能只需要在鼠标悬停和鼠标悬停时将元素上的属性或数据设置为悬停或不悬停,这很可能是您和我们中的任何人阅读本文时想到的第一件事。
  • 检查jQuery source code。我认为他们使用mouseovermouseout 进行悬停。
  • @Antony:我没有看到它被引用到其他任何地方,所以fn.hover 很可能与:hover 选择器无关。不过,我可能错了。
  • 我不认为 jquery 首先支持:$(element).is(':hover') // => Error: Syntax error, unrecognized expression: unsupported pseudo: hoverjsfiddle
  • 一个蹩脚解决方案:jsfiddle.net/czpkz/1

标签: javascript jquery hover


【解决方案1】:

简单地使用 element.matches(':hover') 似乎对我来说效果很好,您也可以为旧版浏览器使用全面的 polyfill:https://developer.mozilla.org/en-US/docs/Web/API/Element/matches

【讨论】:

  • 这似乎对我在 Chromium 或 Firefox 上不起作用,除非我使用 [element]:hover#[id]:hover*:hover 崩溃,body *:hover:root *:hoverbody :hover:root :hover 也不起作用。
【解决方案2】:

你可以使用querySelectorfor 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回答。

【讨论】:

  • 我会将其扩展到!!(e.querySelector(":hover") || e.parentNode.querySelector(":hover") === e)
  • @megawac 只是举了一个我为什么不这样做的例子
  • @zb 您好,我知道这是一篇旧帖子,但如果您还在那里,您介意向我解释一下您的代码吗?特别是那些行 document.addEventListener('mousemove', function checkHover() {console.log(hovered ? 'hovered' : 'not hovered'); 从未见过甚至不知道它是如何工作的
  • @Luke,最后是 ternar 条件,google 一下。首先只是事件,监听,(触发检查悬停,可以是setTimeout,但是mousemove看起来更相关)
【解决方案3】:

首先,您需要跟踪悬停在哪些元素上。这是一种方法:

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

【讨论】:

  • 编辑以使用 matches 原生函数(包括供应商前缀)
  • 为什么这是正确答案?问题要求不使用鼠标悬停?
  • 此答案使用可用的本机功能,回退到mouseover/mouseout 以保持问题的“浏览器兼容”部分。
  • @Niet 嗨,我无法让这段代码工作,它非常复杂,我不确定它在做什么。你能帮我理解吗?
  • 我想知道为什么这段代码得到了 8 个赞。它过于复杂,并不能解决问题。只是想弄清楚你想用这个做什么,我花了 30 分钟。不清楚且令人困惑。
【解决方案4】:

我想到检查元素是否悬停的一种方法是在 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 get Styles

如果有人能想到比solid/dashed 更好的css 属性用作标志,请告诉我。最好该属性是很少使用且不能继承的属性。

【讨论】:

  • 这有点hacky,但我绝对最喜欢这种方式,因为它非常合乎逻辑,简单且没有兼容性问题。
猜你喜欢
  • 2011-05-26
  • 1970-01-01
  • 2015-08-08
  • 2017-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-04
相关资源
最近更新 更多