There's no equivalent purely in WebAssembly text format because the WebAssembly environment doesn't know anything about the DOM (or any of the browser APIs) or how to manipulate it.
What WebAssembly can do though is import functions from its host environment, such as the browser. You can then call those functions from within WebAssembly using the call
instruction by providing the imported function index or by a name.
Here's an example of incrementing a static (global) in WebAssembly and then updating the DOM based on the count:
;; clicks.wat
(module
;; import the updateClickCount function from JavaScript land
(import "button" "updateClickCount"
(func $updateClickCount
(param $x i32)
)
)
;; Define a mutable static i32 initialized at 0
(global $count (mut i32) (i32.const 0))
;; Define and export a function to JS land
(func (export "onClick")
;; Increment the global count
get_global $count
i32.const 1
i32.add
set_global $count
;; Push the count on the stack and call the imported function
get_global $count
call $updateClickCount
)
)
This might be the corresponding HTML/JS to load and set the imports and hook up to the DOM:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Clicks</title>
</head>
<body>
<button id="click">CLICK ME</button>
<p id="numclicks"></p>
<script>
// This is what we'll make available to wasm
const imports = {
button: {
updateClickCount: (num) => document.getElementById('numclicks').innerHTML = num.toString()
}
};
WebAssembly.instantiateStreaming(fetch('clicks.wasm'), imports)
.then(obj => {
const exports = obj.instance.exports;
// When the button is clicked, call the function in wasm
document.getElementById('click').addEventListener('click', () => {
exports.onClick();
});
}).catch((err) => console.error(err));
</script>
</body>
</html>
WebAssembly studio example (click build and run): https://webassembly.studio/?f=ff0fei4xgd9