You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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);

优化说明

  1. 替换定时器为requestAnimationFrame:浏览器会根据屏幕刷新率自动调整帧率,彻底解决卡顿问题
  2. 修正光标定位逻辑:通过transform: translate(-50%, -50%)让光标中心对齐鼠标,改用fixed定位避免滚动偏移
  3. 平滑显示/隐藏:用opacity+visibility配合过渡动画替代display: none,避免突兀的显示切换
  4. 避免事件遮挡:添加pointer-events: none,防止自定义光标挡住下方元素的鼠标事件
  5. 精简逻辑:用布尔值控制光标更新状态,减少不必要的计算

效果示例

图片Hover时自定义光标效果示例

内容的提问来源于stack exchange,提问作者passionFinder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 11:40:32