纯JavaScript实现Material涟漪效果时遇circle undefined错误求助
修复Material涟漪效果的点击报错问题
错误原因
target.classList.add("ripple")无返回值,导致circle变量为undefined,后续调用circle.getElementsByClassName()抛出类型错误。- 原代码试图操作伪元素(
::after),但伪元素不属于DOM节点,无法通过DOM方法获取或删除,逻辑完全错误。
修正方案
改为动态创建涟漪DOM元素,精准控制其生命周期和位置,更符合Material交互逻辑:
HTML(无需修改)
<div class="my-ripple">Click me</div>
CSS(调整涟漪样式)
.my-ripple { position: relative; overflow: hidden; display: inline-block; width: auto; padding: 1.2rem; font-family: sans; cursor: pointer; border-radius: 10px; background: #eee; /* 添加背景便于观察效果 */ } .ripple { position: absolute; border-radius: 50%; transform: scale(0); animation: ripple 600ms linear; background-color: rgba(0, 0, 0, 0.5); pointer-events: none; /* 避免阻挡后续点击 */ } @keyframes ripple { to { transform: scale(4); opacity: 0; } }
JavaScript(核心逻辑修正)
function createRipple(event) { const target = event.currentTarget; // 移除已存在的涟漪元素 const existingRipple = target.querySelector('.ripple'); if (existingRipple) { existingRipple.remove(); } // 创建新涟漪元素 const ripple = document.createElement('span'); ripple.classList.add('ripple'); target.appendChild(ripple); // 根据点击坐标设置涟漪位置和大小 const rect = target.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); const x = event.clientX - rect.left - size / 2; const y = event.clientY - rect.top - size / 2; ripple.style.width = ripple.style.height = `${size}px`; ripple.style.left = `${x}px`; ripple.style.top = `${y}px`; // 动画结束后自动清理元素 ripple.addEventListener('animationend', () => { ripple.remove(); }); } const buttons = document.getElementsByClassName("my-ripple"); for (const button of buttons) { button.addEventListener("click", createRipple); }
关键改进点
- 用独立DOM元素替代伪元素,解决伪元素动画无法重复触发的问题
- 根据点击位置计算涟漪起始坐标,还原Material设计的交互体验
- 动画结束后自动清理元素,避免DOM节点堆积
- 移除错误的变量赋值逻辑,彻底消除类型错误
内容的提问来源于stack exchange,提问作者Designer
相关产品推荐
相关产品推荐

