[英]Hover the element below the mouse cursor when scrolling
可以使用以下技術確定鼠標光標下方的元素(即最頂部的懸停元素):
mousemove
事件。 目標是
event.target
或 document.elementFromPoint(event.clientX, event.clientY)
。 在不移動鼠標的情況下滾動時,這不起作用。 然后,鼠標在技術上不動; 因此,不會發生任何鼠標事件。
不幸的是,在收聽scroll
事件時,上述兩種技術都不再適用。 event.target
將是滾動(或document
)的任何元素。 此外,鼠標光標位置未在event
對象上公開。
正如在“確定鼠標指針位於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
(即事件偵聽器附加到的元素)。 對於scroll
部分,您可以使用hoverTarget.closest
在DOM樹中查找合適的元素。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.