本文介绍如何在自定义光标(custom cursor)中,通过监听元素的 data-img 属性,在鼠标悬停时动态加载并显示对应图片,同时保持 DOM 轻量——图片仅在需要时渲染,空状态自动隐藏。
本文介绍如何在自定义光标(custom cursor)中,通过监听元素的 `data-img` 属性,在鼠标悬停时动态加载并显示对应图片,同时保持 dom 轻量——图片仅在需要时渲染,空状态自动隐藏。
在构建高性能、视觉丰富的自定义光标系统时,一个常见需求是:当用户悬停在特定元素(如项目卡片、链接或图文标签)上时,光标区域不仅改变样式或显示文字,还能动态加载并展示一张关联缩略图,从而增强交互反馈与沉浸感。本教程将基于你已有的轻量级光标逻辑(使用 transform 实现高性能跟随),提供一套简洁、健壮且跨浏览器友好的实现方案。
与其在 JavaScript 中反复创建/销毁 <img> 元素(带来不必要的 DOM 操作开销),我们采用更高效的方式:
✅ HTML 中保留一个静态 <img> 元素(如 <img src="" class="cursor__img">);
✅ CSS 通过属性选择器自动控制其可见性;
✅ JS 仅负责读取 data-img 并更新 src 属性。
这样既避免了频繁的 DOM 插入/移除,又确保了 Safari、Chrome、Firefox 等主流浏览器下的稳定表现(尤其规避了 Safari 中因动态节点导致的渲染抖动问题)。
确保你的 .cursor 容器内已包含目标 <img> 元素:
<div class="cursor"> <span></span> <div class="cursor__label"></div> <img src="" class="cursor__img"> <!-- 初始 src 为空,由 JS 控制 --></div>
添加以下 CSS 规则,让 src="" 的图片自动隐藏:
.cursor__img[src=''] { display: none;}/* 可选:统一尺寸与定位 */.cursor__img { width: 25px; height: 25px; position: absolute; top: 8px; left: 8px; pointer-events: none; /* 确保不干扰鼠标事件 */ z-index: 2;}
⚠️ 注意:pointer-events: none 是必须的,否则图片可能遮挡底层元素,导致 mouseleave 误触发。
复用你已有的选择器逻辑,精准匹配含 data-img 的元素(例如 .test-image):
const hasImg = document.querySelectorAll('.test-image');const cursorImg = document.querySelector('.cursor__img');hasImg.forEach(item => { const imgSrc = item.dataset.img; item.addEventListener('mouseenter', () => { if (imgSrc) { cursorImg.src = imgSrc; // 可选:预加载图片防止首次悬停闪烁(见下方提示) const img = new Image(); img.src = imgSrc; } }); item.addEventListener('mouseleave', () => { cursorImg.src = ''; // 触发 .cursor__img[src=''] 隐藏规则 });});
? 提示:为提升体验,可在 mouseenter 中主动预加载图片(如上所示),避免首次悬停时出现空白延迟。
cursorImg.addEventListener('error', () => { cursorImg.style.display = 'none';});
本方案以「最小变更、最大兼容」为原则:
? 不修改现有光标移动逻辑(仍基于 transform + setTimeout 防抖);
? 不引入新依赖或复杂状态管理,纯原生 JS + CSS 属性驱动;
? 兼顾性能与可维护性——DOM 静态、样式可控、逻辑清晰。
最终效果:当用户悬停在 <p class="test-image" data-img="path/to/img.png"> 上时,光标右上角将平滑浮现对应图片;移出后自动隐藏,整个过程无闪烁、无卡顿,完美适配你当前优化过的光标架构。