快速滚动时,您使用哪个事件来即时检测元素上的光标?

问题描述 投票:0回答:1

我注意到当我在元素上快速滚动时,不会触发诸如滚轮或鼠标悬停之类的事件。你在这种情况下使用什么?

我尝试使用滚轮和鼠标悬停事件

javascript dom
1个回答
0
投票

为了解决这个问题,您可以尝试计算滚动时最后一个位置相对于您的元素的位置。只需存储最后一个

clientX
clientY
,然后比较该点是否触及滚动上的目标之一。还要添加
mouseleave
mouseenter
事件侦听器,因为我们在这里切换一个类,无论滚动如何,我们都希望在鼠标不在它上面时删除它。

function pointInBBox( x, y, element ){
    
  const bb = element.getBoundingClientRect();
  
  // Check if the [x,y] point is inside the DOMRect() bounding box.
  return x >= bb.left
    && x <= bb.left + bb.width
    && y >= bb.top
    && y <= bb.top + bb.height;
  
}

const targets = [...document.querySelectorAll( '.target' )];

let x = 0, y = 0, currentTarget;

// This will store the x and y position of the mouse
document.addEventListener( 'mousemove', event => {
  
  x = event.clientX;
  y = event.clientY;
  
});

document.addEventListener( 'scroll', event => {
   
   // Find the first element that the mouse is over (for efficiency)
   const mouseIsOver = targets.find(div => pointInBBox( x, y, div ));
   
   // Remove the class from the last target if one exists
   if( currentTarget ) currentTarget.classList.remove( 'mouse-over' );
   // Add the class to the new target if it exists
   if( mouseIsOver ) mouseIsOver.classList.add( 'mouse-over' );
   // Assign the target so we can remove the class later
   currentTarget = mouseIsOver;
   
});

targets.forEach(target => {
  
  // Make sure we add the class in regular non-scrolling mode as well
  target.addEventListener( 'mouseenter', event => {

    if( currentTarget ) currentTarget.classList.remove( 'mouse-over' );
  
    currentTarget = target;
    currentTarget.classList.add( 'mouse-over' );

  });
  // And the same here, remove the class if the mouse leaves when we're not scrolling
  target.addEventListener( 'mouseleave', event => {

    if( target === currentTarget ) currentTarget = null;

    target.classList.remove( 'mouse-over' );

  });

})
html, body { height: 100%; }
body { padding: 0; margin: 0; }
.target { width: 100vw; height: 100vh; display: flex; }
.target:after { content: 'mouse in here'; margin: auto; font-size: 50px; color: white; text-shadow: 0 0 20px black; opacity: 0; }
.target.mouse-over:after { opacity: 1; transition: opacity .2s; }
<div class="target" style="background:red"></div>
<div class="target" style="background:orange"></div>
<div class="target" style="background:yellow"></div>
<div class="target" style="background:green"></div>
<div class="target" style="background:teal"></div>
<div class="target" style="background:blue"></div>
<div class="target" style="background:purple"></div>
<div class="target" style="background:magenta"></div>

© www.soinside.com 2019 - 2024. All rights reserved.