通过 web_sys 创建时没有在元素上定义单击方法

问题描述 投票:0回答:1

在 JavaScript 控制台中,我可以执行以下命令来创建

<input>
元素并演示它具有
click
方法。

let input = document.createElement("input");
input.type = "file";
console.log(input.click);
// ƒ click() { [native code] }

如果我尝试在编译为

wasm
的 Rust 中执行以下操作,则会收到错误:

let document: Document = Document::new().unwrap();
let input: Element = document.create_element("input").unwrap();
input.set_attribute("type", "file").unwrap();

# For debugging purposes, save a reference to a global variable so I can inspect it from the JavaScript console
let input_jsval : JsValue = input.clone().into();
js_sys::Reflect::set(&js_sys::global(), &JsValue::from_str("debug_input"), &input_jsval).unwrap();

# Attempt to click it
let input_html_element: HtmlElement = input_jsval.clone().into();
input_html_element.click();

当我运行

wasm
测试时,它会产生:

failures:

---- wasm_tests::tests::input_test output ----
    log output:
    
    error output:
        wasm-bindgen: imported JS function that was not marked as `catch` threw an error: getObject(...).click is not a function
        
        Stack:
        TypeError: getObject(...).click is not a function
            at http://127.0.0.1:8000/wasm-bindgen-test:589:25

如果我检查 JavaScript 控制台,我可以看到我保存的引用上没有

click
方法。

debug_input.click
// undefined

那么,为什么当我通过 JavaScript 创建

<input>
时,它会得到一个
click
方法,但如果我通过
wasm
做本质上相同的事情,它却不会呢?我怀疑通过
Element
HtmlElement
JsValue
的转换是有损的?有没有更直接的转换方式?

rust webassembly wasm-bindgen web-sys
1个回答
0
投票

Q1: 有没有更直接的将

Element
转换为
HtmlElement

A1:是的,如果您知道它确实是

HtmlElement
,那么您就可以
let input_html_element: HtmlElement = input.dyn_into().unwrap(); 
。但是,如果输入实际上不是
HtmlElement
,则此操作将会失败,而本例则不是。

Q2:为什么不是

HtmlElement

A2:MDN 表示

Document::createElement
将返回“[a] 新的
HTMLElement
...如果文档是
HTMLDocument
,这是最常见的情况。否则将返回新的
Element
Document::new()
API 不会获取对当前窗口
document
的引用,而是创建一个新的(非 HTML)文档。相反,请使用:

let document: Document = web_sys::window().unwrap().document().unwrap();
© www.soinside.com 2019 - 2024. All rights reserved.