如何用原生JS实现类似Vue的class绑定,完成深色模式切换动画
核心问题梳理
你现有代码的问题主要集中在以下几点:
- 给开关添加
pull动画类后立即清空,导致0.5s的动画完全无法触发 - 没有对应Vue示例中的
animationend事件监听,无法在动画结束后正确重置状态,会导致下次点击无法重新触发动画 - 直接操作
className会覆盖元素原有其他样式类,且主题初始化逻辑存在冗余 - 主题切换时机和动画进度没有匹配,交互体验不连贯
修正后完整代码
HTML 部分(确保元素id匹配)
<div id="switch" class="switch"></div>
你现有的CSS代码不需要改动,如果需要主题切换时的颜色过渡效果,可以额外添加以下样式:
body { transition: background-color 0.3s, color 0.3s ease; }
JS 部分
const switchEl = document.getElementById('switch'); // 页面加载时初始化本地存储的主题 if (localStorage.getItem('css')) { document.body.classList.add('dark'); } // 监听动画结束事件,自动重置动画类,保证下次点击可重新触发动画 switchEl.addEventListener('animationend', () => { switchEl.classList.remove('pull'); }); // 点击切换逻辑 switchEl.addEventListener('click', () => { // 先触发拉绳下落动画 switchEl.classList.add('pull'); // 动画执行到中间节点(拉绳落到最低点)时切换主题,匹配交互逻辑 setTimeout(() => { const isDark = document.body.classList.contains('dark'); if (isDark) { document.body.classList.remove('dark'); localStorage.removeItem('css'); } else { document.body.classList.add('dark'); localStorage.setItem('css', 'dark'); } }, 250); });
补充说明
如果希望拉绳动画完全结束后再切换主题,将setTimeout的延时参数从250改为500即可。
内容的提问来源于stack exchange,提问作者漫磋嗟
相关产品推荐
相关产品推荐

