如何使用JavaScript或jQuery实现图片Hover时切换自定义光标?
问题:图片Hover时实现流畅的150x150自定义光标效果
我正在开发一个功能,要求鼠标悬停在图片上时,显示一个150x150尺寸的自定义光标。尝试了一些方案,但始终无法实现流畅的悬停效果。
现有代码
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script> <div class="article-thumbnail-section"> <div class=""> <img src="https://via.placeholder.com/100" class="card_bg11 article-thumbnail-ellipse odd"> <img src="https://via.placeholder.com/100" class="card_bg12 article-thumbnail-ellipse even"> <img src="https://via.placeholder.com/100" class="card_bg13 article-thumbnail-ellipse odd"> <img src="https://via.placeholder.com/100" class="card_bg14 article-thumbnail-ellipse even"> </div> <div class="article-thumb-inner"> <div class="article-thumb-inner-sec"> <div class=" article-thumbnail-div odd"><img src="https://vignette1.wikia.nocookie.net/cityville/images/5/58/Viral_basketballcomplex_basketball_200x200.png/revision/latest?cb=20130613014636" class="lazyload card-img-top article-thumbnail-img" alt="Period 101" /></div> <div class=" article-thumbnail-div even"><img src="https://vignette1.wikia.nocookie.net/cityville/images/5/58/Viral_basketballcomplex_basketball_200x200.png/revision/latest?cb=20130613014636" class="lazyload card-img-top article-thumbnail-img" alt="My First Period" /></div> <div class=" article-thumbnail-div odd"><img src="https://vignette1.wikia.nocookie.net/cityville/images/5/58/Viral_basketballcomplex_basketball_200x200.png/revision/latest?cb=20130613014636" class="lazyload card-img-top article-thumbnail-img" alt="Period Hacks" /></div> <div class=" article-thumbnail-div even"><img src="https://vignette1.wikia.nocookie.net/cityville/images/5/58/Viral_basketballcomplex_basketball_200x200.png/revision/latest?cb=20130613014636" class="lazyload card-img-top article-thumbnail-img" alt="My First Period" /></div> <div id="badge1" class="badge1"></div> </div> </div> </div>
CSS
.article-thumbnail-section { position: relative; min-height: 400px; } .article-thumbnail-section img { position: absolute; } .article-thumb-inner { position: absolute; top: 0; bottom: 0; right: 0; left: 0; } .article-thumb-inner-sec { position: absolute; z-index: 999; height: 100%; width: 100%; } .article-thumbnail-div { position: absolute; width: 212px; cursor: pointer; z-index: 10; height: 226px; } .article-thumbnail-div img { z-index: 5; } .article-thumbnail-div:nth-child(1) { left: 0%; } .article-thumbnail-div:nth-child(2) { left: 27%; } .article-thumbnail-div:nth-child(3) { right: 27%; } .article-thumbnail-div:nth-child(4) { right: 0%; } .article-thumbnail-div.even { top: 20%; } .article-thumbnail-ellipse { top: 50%; } .article-thumbnail-ellipse:nth-child(1) { left: -90px; } .article-thumbnail-ellipse:nth-child(2) { left: 22%; } .article-thumbnail-ellipse:nth-child(3) { right: 20%; } .article-thumbnail-ellipse:nth-child(4) { right: -90px; } .article-thumbnail-ellipse.odd { top: 10%; } .article-thumbnail-ellipse.even { top: -2%; } #badge1 { position: fixed; width: 150px; height: 150px; background: url('https://3boysandadog.com/wp-content/uploads/2014/09/icon_circle_150x150.png') no-repeat; opacity: 0; visibility: hidden; pointer-events: none; z-index: 250; transition: opacity 0.2s, visibility 0.2s; transform: translate(-50%, -50%); } #badge1.on { opacity: 1; visibility: visible; }
JavaScript
const customCursor = document.getElementById('badge1'); let isHovering = false; let lastEvent; // 实时更新光标位置 function updateCursorPosition() { if (!isHovering || !lastEvent) return; customCursor.style.left = `${lastEvent.clientX}px`; customCursor.style.top = `${lastEvent.clientY + window.scrollY}px`; } // 用requestAnimationFrame实现流畅动画循环 function animateCursor() { updateCursorPosition(); requestAnimationFrame(animateCursor); } // 记录最新鼠标事件 document.addEventListener('mousemove', (e) => { lastEvent = e; }); // 监听图片容器的hover状态 $(".article-thumbnail-div").hover( function() { isHovering = true; customCursor.classList.add("on"); }, function() { isHovering = false; customCursor.classList.remove("on"); } ); // 启动动画 requestAnimationFrame(animateCursor);
优化说明
- 替换定时器为
requestAnimationFrame:浏览器会根据屏幕刷新率自动调整帧率,彻底解决卡顿问题 - 修正光标定位逻辑:通过
transform: translate(-50%, -50%)让光标中心对齐鼠标,改用fixed定位避免滚动偏移 - 平滑显示/隐藏:用
opacity+visibility配合过渡动画替代display: none,避免突兀的显示切换 - 避免事件遮挡:添加
pointer-events: none,防止自定义光标挡住下方元素的鼠标事件 - 精简逻辑:用布尔值控制光标更新状态,减少不必要的计算
效果示例

内容的提问来源于stack exchange,提问作者passionFinder
相关产品推荐
相关产品推荐

