如何在Leptos中通过NodeRef操作HTML元素的style属性以重新触发动画?
如何在Leptos中通过NodeRef操作HTML元素的style属性以重新触发动画?
嘿,我完全懂你现在的困扰——想用Leptos的NodeRef复刻JS里切换动画名称重新触发动画的逻辑,但发现tachys提供的.style()方法和你预想的不一样对吧?别着急,我们一步步来解决这个问题。
首先得明确:Leptos的NodeRef拿到的元素是tachys封装后的类型,它的.style()方法是用来批量应用样式规则的,不是直接操作原生DOM的style属性。要实现你要的动画切换,得先拿到原生的WebSys DOM元素,再用原生API操作style属性。
下面是调整后的代码,完全贴合你的需求:
use leptos::*; use web_sys::HtmlElement; #[component] pub fn MyComponent() -> impl IntoView { let error_text_node_ref = NodeRef::<P>::new(); let (error_text, set_error_text) = signal("".to_string()); let some_on_click_handler = Callback::new(move |_evt: FretClickEvent| { if let Some(node) = error_text_node_ref.get() { // 把tachys封装的元素转换成原生DOM元素 let element = node.as_ref().dyn_into::<HtmlElement>().expect("Failed to get HTML element"); // 获取当前的动画名称,和JS逻辑对齐 let current_anim = element.style().animation_name().unwrap_or_default(); // 切换动画名称,重新触发动画 if current_anim == "shake" { element.style().set_animation_name("shake2").unwrap(); } else { element.style().set_animation_name("shake").unwrap(); } // 如果你不想定义两个动画,也可以用「清空-重置」的方式: // element.style().set_animation_name("").unwrap(); // // 加个0延迟让DOM更新,确保动画能重新触发 // leptos::window().set_timeout_with_callback( // move || { // element.style().set_animation_name("shake").unwrap(); // }, // 0, // ).unwrap(); } // 这里放你设置error_text的其他逻辑.. }); view!{ <p node_ref=error_text_node_ref class="text-center text-red-600 animate-once animate-duration-150 animate-jump-in"> {error_text} </p> } }
简单解释下关键步骤:
- 用
node.as_ref()拿到tachys元素底层的Element,再通过dyn_into转换成HtmlElement(因为你操作的是<p>标签,也可以用HtmlParagraphElement,兼容性更好)。 - 用原生API
element.style().animation_name()获取当前动画名称,用set_animation_name()切换名称,和你原来的JS逻辑完全一致。 - 如果你不想额外定义
shake2动画,注释里的「清空-重置」方案也可行,只需要加个0延迟的定时器,让DOM有时间更新状态,确保动画能重新触发。
备注:内容来源于stack exchange,提问作者mario.b
相关产品推荐
相关产品推荐

