簡體   English   中英

滾動時將元素懸停在鼠標光標下方

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM