gpt4 book ai didi

javascript - 滚动时将元素悬停在鼠标光标下方

转载 作者:行者123 更新时间:2023-11-29 10:59:06 28 4
gpt4 key购买 nike

可以使用以下技术确定鼠标光标下方的元素(即最上方悬停的元素):

  • 监听 mousemove 事件。目标是
    • event.target
    • document.elementFromPoint(event.clientX, event.clientY)

这在不移动鼠标的情况下滚动时不起作用。然后,从技术上讲,鼠标不会移动;因此,不会触发鼠标事件。

不幸的是,当监听 scroll 事件时,上面的两种技术都不再适用。 event.target 将是滚动的元素(或 document)。此外,鼠标光标位置不会暴露在 event 对象上。

this answer to “Determine which element the mouse pointer is on top of in Javascript” 中所述,一种可能的解决方案是通过 CSS :hover 伪类查询悬停元素。

document.addEventListener('scroll', () => {
const hoverTarget = document.querySelector('.element:hover');
if (hoverTarget) {
hover(hoverTarget);
}
});

但是,这是不可用的,因为它非常低效且不准确。 scroll 事件是快速触发的事件之一,在执行任何代价稍高的事情(例如查询 DOM)时需要放慢速度。

此外,悬停元素在滚动时滞后。您可以在具有大量链接的任何类型的网站上观察到这一点:将鼠标悬停在其中一个链接上并在不移动鼠标的情况下滚动到另一个链接。它仅在几毫秒后更新。

有没有什么办法可以很好且高效地实现?基本上,我想要 mouseenter 的反函数:我不想知道鼠标何时进入元素,而是想知道元素何时与鼠标相交(例如,当鼠标未移动但元素 [即滚动时]).

最佳答案

解决此问题的一种方法是使用 mousemove 事件存储鼠标光标位置,并在 scroll 事件中使用 document.elementFromPoint(x, y) 找出应该悬停的元素。

请记住,由于以如此高的频率触发 scroll 事件,这仍然非常低效。事件处理程序应该去抖动以将函数的执行限制为每次延迟一次。 David Walsh 在 JavaScript Debounce Function 中解释了如何执行此操作.

let hoveredElement;
let mouseX = 0, mouseY = 0;

document.addEventListener('DOMContentLoaded', () => {
document.addEventListener('mousemove', event => {
mouseX = event.clientX;
mouseY = event.clientY;

hover(event.target);
});

document.addEventListener('scroll', () => {
const hoverTarget = document.elementFromPoint(mouseX, mouseY);
if (hoverTarget) {
hover(hoverTarget);
}
});
});

function hover(targetElement) {
// If the target and stored element are the same, return early
// because setting it again is unnecessary.
if (hoveredElement === targetElement) {
return;
}

// On first run, `hoveredElement` is undefined.
if (hoveredElement) {
hoveredElement.classList.remove('hover');
}

hoveredElement = targetElement;
hoveredElement.classList.add('hover');
}
.element {
height: 200px;
border: 2px solid tomato;
}

.element.hover {
background-color: lavender;
}
<div class="container">
<div class="element element-1">1</div>
<div class="element element-2">2</div>
<div class="element element-3">3</div>
<div class="element element-4">4</div>
<div class="element element-5">5</div>
</div>

目前,该解决方案在移动鼠标和滚动时都会将最顶部的元素悬停在鼠标下方。将 mousemove 监听器附加到一组特定元素,然后始终悬停 event.currentTarget (即事件监听器附加到的元素)可能更适合您的需要).至于滚动部分,您可以使用hoverTarget.closest在DOM树中找到合适的元素。

关于javascript - 滚动时将元素悬停在鼠标光标下方,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50700378/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com