0x00 开篇
经过文章Rust 与 Wasm
咱们基本了解了 JavaScript是怎么调用Rust的函数,那本篇文章将带你了解运用 Rust 来调用 JavaScript 函数以及操作 Dom。
本篇文章阅读时刻大约8分钟。
0x01 调用 JavaScript 函数
因为 Rust 是一门静态言语,所以在 Rust 中调用的 JavaScript 函数时必须声明。声明的办法如下:
#[wasm_bindgen]
extern "C" {
// js 函数
pub fn demo()
}
假如咱们声明一个alert
函数,示例代码如下:
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
// js 函数
fn alert(msg: &str);
}
#[wasm_bindgen]
pub fn alert_by_rust(msg: &str) {
return alert(msg);
}
所以,只要咱们能够正确的声明 JavaScript 的函数,咱们能够调用恣意的 JavaScript 函数。
0x03 运用 web_sys 调用 JavaScript 函数
看了上面的办法,不知道大家有没有发现缺点。JavaScript 的函数太多了,咱们该怎么正确声明 JavaScript 的函数呢?即便咱们正确声明了,后期维护起来或许也会很难。所以咱们能够凭借这两个 crate ——js-sys
和web-sys
。这个库现已帮咱们都声明好了,拿来用即可。
-
js-sys
:包括 ECMAScript 标准的大局范围一些变量和办法,不包括 Html节点操作,Web接口等其它环境的API。 -
web-sys
:根据js-sys
并提供在浏览器内的接口,包括Web、Html节点操作等。
所以,在浏览器里上面两个 crate 要一起导入。先演示下用法:
use js_sys::Function;
use wasm_bindgen::prelude::*;
use web_sys::window;
/// 调用 setTimeout
#[wasm_bindgen]
pub fn test_setTimeout() {
// 声明一个函数
let func = Function::new_no_args(r#"alert("hello wasm")"#);
// 获取 window
let window = window().unwrap();
// window 调用setimeout
window.set_timeout_with_callback_and_timeout_and_arguments_0(&func, 1000);
}
注:因为web-sys
存在多个 feature ,所以要参照文档,用到哪个类或许函数,就要声明哪个 feature。
上面的代码我就不演示了,有没有突然感觉到变得简单了起来。其实咱们能够看下js-sys
的源码,确实是给咱们现已声明好了,现已省去了咱们很多开发时刻了。
0x04 运用 web_sys 操作 Dom
咱们持续来感受下web_sys
的强大吧,运用 web_sys
操作 Dom 同咱们运用 JavaScript 大同小异,直接上代码:
/// 操作Dom
#[wasm_bindgen]
pub fn dom() {
// 获取window
let window = window().unwrap();
// 获取document
let doc = window.document().unwrap();
// 获取test节点(我在html声明了一个div)
let test_node = doc.get_element_by_id("test").unwrap();
// 在节点里添加内容
test_node.set_text_content(Some("Rust 操作 Dom"));
// 最终再来个alert
window.alert_with_message("我是经过 web_sys 生成的");
}
注:上面的代码用到的 feature 有Window
,Document
,Element
,Node
。所以要在.toml
文件里需求声明。
web-sys = { version = "0.3.60", features = ["Window", "Document", "Element", "Node"] }
Html 代码也贴一下吧:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Rust Wasm 测试</title>
</head>
<script type="module">
import init, {alert_by_rust, dom, test_setTimeout} from "./pkg/rust_wasm_dom.js";
init().then(() => {
// alert_by_rust("hello world!")
dom()
});
</script>
<body>
<!-- 声明的div节点 -->
<div id="test"></div>
</body>
</html>
编译直接看作用。
0x05 小结
看完文章了,有没有感觉到很简单。其实本篇文章的内容也比较少,关键是把握js-sys
和web-sys
这两个 crate。能够说如果你学会了 Rust,那么你又把握了一门能够写 wasm 的言语,而且或许写起来变得愈加简单。说道这儿或许有读者会考虑到,如果这个 web 端我全部运用 Rust 构建的 wasm 来写,是不是就不需求 JavaScript 了。其实上一篇文章我也提到过,感兴趣的读者能够研讨下Yew
这个结构。
最终说句题外话吧,近几年我发现前端的技能是更新最快的,每几个月就会呈现新的前端结构,感觉每个言语都想取代 JavaScript,取代前端,我能够说前端是最卷的IT工作,没有之一。哎,疼爱各位前端开发工程师们了。
0x06 参考资料
-
js-sys crate:
docs.rs/js-sys/0.3.…
-
web-sys crate:
docs.rs/web-sys/0.3…
-
wasm-bindgen文档:
rustwasm.github.io/wasm-bindge…
-
MDN Web docs 中文:
developer.mozilla.org/zh-CN/docs/…