Alert with button ⚙️
Now let's look at building some DOM.
First we'll need to add some more APIs as features to our Cargo.toml:
features = [
"Document",
"Element",
"EventTarget",
"HtmlElement",
"Node",
"Window",
]
Then we can write our app:
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use web_sys::{
window,
Element,
HtmlElement,
Node
};
pub fn main() -> Result<(), JsValue> {
// Get a handle to our window and document
let window = window().unwrap();
let document =
window
.document()
.unwrap();
// Create the button element
let button:Element =
document
.create_element("button")
.unwrap();
button
.dyn_ref::<HtmlElement>()
.unwrap()
.set_inner_text("Trigger");
// Get a handle on the document's body
let body =
document
.body()
.unwrap();
// Add the button to the DOM
body
.dyn_into::<Node>()
.unwrap()
.append_child(&button)
.unwrap();
// Create a Javascript closure that will trigger an alert
let cb =
Closure::wrap(Box::new(|| {
web_sys::window()
.unwrap()
.alert_with_message("You hit the button!")
.unwrap();
}) as Box<dyn FnMut()>);
// Add the closure as a listener that procs on click
button
.add_event_listener_with_callback("click", cb.as_ref().unchecked_ref())
.unwrap();
// Usually Rust would hold on to the closure (or else it is dropped)
// but here we'll forget about it, which means it will be around forever.
cb.forget();
Ok(())
}
And see our work completed!
That's an awful lot of code for a simple button that triggers an alert, but it's fast and it's cautious.