怎样利用JavaScript实现页面动态效果【教程】

11次阅读

document.querySelector 与 classList.toggle 是实现页面动态效果最轻量可靠的基础组合,应通过 css 类而非 style.display 控制显隐,用 requestAnimationFrame 替代 setTimeout 实现平滑动画,scroll/resize 需节流,且需根据环境判断动效必要性与降级策略。

怎样利用JavaScript实现页面动态效果【教程】

document.querySelectorclasslist.toggle 是实现大多数页面动态效果最轻量、最可靠的基础组合。

点击切换元素显隐,别用 display: none 硬切

直接操作 style.display 会覆盖 CSS 中定义的其他显示逻辑(比如响应式断点里的 display: flex),也难维护。更稳妥的方式是通过 CSS 类控制:

button.addEventListener('click', () => {   const panel = document.querySelector('#sidebar');   panel.classList.toggle('is-hidden'); });

对应 CSS 写成:

.is-hidden {   display: none !important; }
  • !important 是为了确保能压过内联样式或其他高优先级规则
  • 避免在 js 里写 panel.style.display = 'none' —— 后续想加过渡动画或适配暗色模式时会卡住
  • 如果需要保留占位空间,改用 visibility: hidden + 单独类名,而非 display

requestAnimationFrame 替代 setTimeout 做逐帧动画

滚动视差、数字滚动计数、进度条填充等需要平滑变化的效果,用 setTimeout 容易掉帧或卡顿。浏览器requestAnimationFrame 有优化调度:

立即学习Java免费学习笔记(深入)”;

function animateCounter(el, target, current = 0) {   if (current >= target) {     el.textContent = target;     return;   }   const step = Math.ceil((target - current) / 20);   el.textContent = Math.min(current + step, target);   requestAnimationFrame(() => animateCounter(el, target, number(el.textContent))); }
  • 不要用 for 循环 + setTimeout 模拟动画 —— 事件队列积会导致延迟不可控
  • requestAnimationFrame 自动匹配屏幕刷新率(通常是 60fps),且标签页非激活时会暂停,省资源
  • 数值类动画务必用 Number() 转类型,避免字符串拼接(如 '10' + 1 === '101'

监听 scrollresize 时必须节流

这些事件在用户操作中高频触发(每秒几十次),不加限制直接执行 dom 操作会严重拖慢页面:

let isThrottled = false; window.addEventListener('scroll', () => {   if (isThrottled) return;   isThrottled = true;   doStickyHeaderLogic();   setTimeout(() => isThrottled = false, 16); // ≈ 60fps 一帧 });
  • setTimeout + 标志位比 Lodash 的 throttle 更轻量,适合简单场景
  • 别在 scroll 回调里调用 getBoundingClientRect()offsetTop —— 触发强制同步布局(Layout Thrashing)
  • 现代方案可考虑 IntersectionObserver 替代 scroll 监听做懒加载或吸顶,它本身已内置性能优化

真正难的不是写出动效,而是判断该不该动、何时停、怎么退化。比如悬停菜单在触摸设备上没 hover,就得 fallback 到点击展开;又比如动画在低性能设备上应自动降级为 class 切换而非逐帧计算。这些细节不在语法里,而在运行时环境的判断中。

text=ZqhQzanResources