【问题标题】:Get element currently under mouse without using mouse events在不使用鼠标事件的情况下获取当前鼠标下的元素
【发布时间】:2014-08-23 16:15:03
【问题描述】:

WRT 构建 Firefox 插件。

是否可以通过一些XPCOM或javascript方法获取鼠标下的元素? (请使用非 js-ctypes,因为这需要操作系统特定性)

当用户按下 Ctrl + Shift + M 时,我想检测鼠标下方的内容。

现在,当用户按下此热键时,我正在向文档添加一个 mouseover 侦听器,因此当他移动它时我可以获取鼠标下的元素,但不能获取他移动时鼠标下的元素按下热键组合。

【问题讨论】:

  • 我建议在mousemove 事件上设置一个监听器来跟踪鼠标。然后使用鼠标的坐标,找到它下面的元素。这很烦人,但可能。在此处查看更多信息:stackoverflow.com/questions/7790725/…
  • elementFromPoint 的问题是我必须添加mousemove,并且在用户按下热键后移动鼠标之前,该元素将不可用。我在这个解决方案中基本上使用第二种方法:stackoverflow.com/a/4711224/3791822
  • 一直收听mousemove,将位置存储在某处。然后当按下组合键时,使用最后记录的鼠标位置。
  • 哦,是的,这是一个想法,我也有这个想法,但忘了提及,所以投票赞成。持久的mousemove 对性能不太好,尤其是在附加范围内,所以我希望避免这种情况。
  • 那么你可能不走运。你确定它对性能有那么大的影响吗?我以前做过这样的事情,没有什么问题。更新数组中 xy 值的简单处理程序不是很费力。这就是它需要做的所有事情。

标签: javascript firefox-addon mouseevent xpcom


【解决方案1】:

我刚刚查看了获取(或存储并提供)光标位置的代码的源代码。我没有找到任何可以使用的东西(来自 Javascript、XPCOM 与否)。我可能漏掉了什么……MXR 是你的朋友。

但是,如果您想避免mousemove(这通常是一个好主意),您可以只寻找最里面的悬停元素,例如像这样。

function getInnermostHovered() {
    var n = document.querySelector(":hover");
    var nn;
    while (n) {
        nn = n;
        n = nn.querySelector(":hover");
    }
    return nn;
}

(fiddle演示原理)

虽然我认为这是一种 hack,但它似乎在大多数情况下都运行良好,但如果元素通过 pointer-events 禁用了鼠标事件,它就会失败。可能还有其他我没有想到的问题...

当然,当文档没有悬停元素(例如鼠标实际上不在文档中)时,这不会返回任何内容。

【讨论】:

  • 这确实是一个聪明的想法——我相信它可以被简化,但是使用 querySelectorAll 因为它的顺序应该总是这样,你想要的元素在最后。即function getInnermostHovered() { return [].slice.call(document.querySelectorAll(':hover')).pop(); }
  • 有趣的想法@SmokeyPHP
  • 确实,Array.from(document.querySelectorAll(":hover")).pop() 可以工作,但是对于非常大的文档,取决于浏览器引擎,我可以想象它会遍历整个树来寻找 :hover,而递归 .querySelector 会修剪子树早期。或者,重要的浏览器可能已经对其进行了足够优化......需要进行一些性能测试。
  • 好点,它的简洁性可能不值得某些文档大小/浏览器的性能损失。我刚刚进行了一些测试,它确实似乎更快(至少在最新的 FF 和 Chrome 中)“手动”遍历更具体的树 - 有时差异可以忽略不计,但仍然存在差异
  • 对于现在看的人来说,MXR 似乎已被 SearchFox 取代。
猜你喜欢
  • 2011-02-05
  • 1970-01-01
  • 1970-01-01
  • 2011-10-06
  • 1970-01-01
  • 2017-06-23
  • 1970-01-01
  • 2022-01-25
相关资源
最近更新 更多