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

Deno Fresh Island中JavaScript动画无法触发的问题排查

问题分析与解决方案

你的代码存在的问题

  1. onLoad事件在div上不生效:onLoad仅对<img>、<script>等媒体/外部资源类元素触发,普通<div>不会触发该事件,导致你的animation函数从未被调用。
  2. 未遵循组件生命周期规范:Deno Fresh基于Preact,Island组件的初始化逻辑应通过useEffect钩子执行,而非依赖元素事件。
  3. DOM元素获取方式不安全:直接使用document.getElementById依赖DOM渲染顺序,且未严谨处理元素不存在的情况。
  4. 未清理定时器:组件卸载时若不清除setInterval,会引发内存泄漏问题。

修正后的代码示例

import { useEffect, useRef } from "preact/hooks";

export default function StartAnimation() {
  const targetRef = useRef(null);
  const intervalRef = useRef(null);

  useEffect(() => {
    const target = targetRef.current;
    if (!target) return;

    let degree = 1;
    function frame() {
      target.style.transform = `rotate(${degree}deg)`;
      degree = degree === 360 ? 0 : degree + 1;
    }

    intervalRef.current = setInterval(frame, 10);

    // 组件卸载时清理定时器
    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
      }
    };
  }, []);

  return (
    <div id="frame">
      <div ref={targetRef}>Test animation</div>
    </div>
  );
}

Deno Fresh中添加动画的标准方式

方式一:JS钩子驱动动画(适合复杂交互场景)

  • 用Preact的useEffect处理组件挂载/更新时的动画初始化,useRef获取目标元素(避免重复查询DOM)。
  • 必须在useEffect的清理函数中清除定时器或取消动画帧,防止内存泄漏。
  • 复杂动画建议用requestAnimationFrame替代setInterval,可与浏览器刷新帧率同步,获得更流畅的效果。

方式二:CSS动画(适合简单、高性能需求)

对于旋转这类基础动画,CSS动画更高效,无需JS参与:

/* 在Island关联的CSS文件中定义 */
@keyframes rotate {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.rotating-element {
  animation: rotate 2s linear infinite;
}

在组件中直接应用类名即可:

export default function StartAnimation() {
  return (
    <div id="frame">
      <div className="rotating-element">Test animation</div>
    </div>
  );
}

这种方式性能更优,浏览器会自动做硬件加速优化,代码也更简洁。

方式三:集成动画库(适合复杂动画场景)

如果需要复杂动画效果,可以引入framer-motion等专业动画库,Fresh的Island支持直接使用第三方npm包,只需在import_map.json中配置依赖即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 12:12:38