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

Yew框架中canvas的onload事件为何始终未触发?

解决Yew中Canvas预初始化的问题

问题分析

第一段代码的问题

Yew的html!宏中绑定的onload是合成事件,仅支持Yew预定义的标准DOM事件(如onclick、oninput等)。而canvas的onload事件仅在通过src属性加载外部图像时才会触发,且Yew并未将其纳入合成事件体系,因此绑定后DOM中不会生成该属性,事件也不会触发。

第二段代码的问题

当Yew函数组件执行时,window.onload事件大概率已经触发完毕(Yew启动应用时,DOM通常已完成加载),此时再设置window.onload回调不会被执行。

正确实现方案

使用Yew的use_effect_with_deps钩子,在组件挂载到DOM后执行Canvas初始化逻辑,确保操作时Canvas元素已存在。

use yew::{function_component, html, use_effect_with_deps};
use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement};
use wasm_bindgen::JsCast;

#[function_component(App)]
fn app() -> yew::Html {
    // 组件挂载后执行Canvas初始化
    use_effect_with_deps(
        |_| {
            // 获取DOM中的canvas元素
            let canvas = web_sys::window()
                .unwrap_throw()
                .document()
                .unwrap_throw()
                .get_element_by_id("main")
                .unwrap_throw()
                .dyn_into::<HtmlCanvasElement>()
                .unwrap_throw();

            // 获取2D绘图上下文
            let ctx = canvas
                .get_context("2d")
                .unwrap_throw()
                .unwrap_throw()
                .dyn_into::<CanvasRenderingContext2d>()
                .unwrap_throw();

            // 执行预初始化操作,示例:绘制红色矩形
            ctx.set_fill_style(&"red".into());
            ctx.fill_rect(10.0, 10.0, 100.0, 100.0);

            web_sys::console::log_1(&"Canvas已完成预初始化".into());

            // 清理函数(此处无资源需要清理,返回空闭包)
            || ()
        },
        (), // 依赖为空,仅在组件首次挂载时执行一次
    );

    html! {
        <canvas id="main" width="200" height="200"></canvas>
    }
}

fn main() {
    yew::start_app::<App>();
}

方案说明

  1. use_effect_with_deps:Yew用于处理副作用的核心钩子,确保代码在组件挂载到DOM后执行,此时Canvas元素已存在于DOM中。
  2. 类型转换:通过dyn_into::<HtmlCanvasElement>将通用DOM元素转换为Canvas专用类型,以便调用Canvas的API。
  3. 上下文获取:获取CanvasRenderingContext2d后即可执行绘图、状态设置等预初始化操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 00:16:15