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>(); }
方案说明
use_effect_with_deps:Yew用于处理副作用的核心钩子,确保代码在组件挂载到DOM后执行,此时Canvas元素已存在于DOM中。- 类型转换:通过
dyn_into::<HtmlCanvasElement>将通用DOM元素转换为Canvas专用类型,以便调用Canvas的API。 - 上下文获取:获取
CanvasRenderingContext2d后即可执行绘图、状态设置等预初始化操作。
内容的提问来源于stack exchange,提问作者ShrimpSalad
相关产品推荐
相关产品推荐

