【问题标题】:How can I access the DOM from WebAssembly text format?如何从 WebAssembly 文本格式访问 DOM?
【发布时间】:2018-08-29 13:24:29
【问题描述】:

这个article 演示了如何从 C 程序访问 WebAssembly 中的 DOM:

#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif

unsigned int EMSCRIPTEN_KEEPALIVE IncrementClickCountOnValue()
{
    // Static variable that hold how many times this function was clicked
    static int clicks=0;

    // Modify the DOM, through a Javascript call provided by EM_ASM_, getElementById  is the DOM API used
    EM_ASM_( {document.getElementById("run").value='Webassembly click count: '+$0}, ++clicks );
    return 1;
}

如果您编译 (emcc dom.c -O1 -s MODULARIZE=1 -s WASM=1 -o dom.js) 并运行它 (emrun --no_browser --port 8080 .),它会按预期工作。

如果没有 C,我怎么能做同样的事情,我。 e. WebAssembly text format 中的 EM_ASM_( {document.getElementById("run").value='Webassembly click count: '+$0}, ++clicks ); 相当于什么?

【问题讨论】:

    标签: dom webassembly


    【解决方案1】:

    没有纯 WebAssembly 文本格式的等价物,因为 WebAssembly 环境对 DOM(或任何浏览器 API)或如何操作它一​​无所知。

    WebAssembly 可以做的是从其宿主环境(例如浏览器)导入函数。然后,您可以通过提供导入的函数索引或名称,使用 call 指令从 WebAssembly 中调用这些函数。

    这是一个在 WebAssembly 中递增静态(全局)然后根据计数更新 DOM 的示例:

    ;; 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
        )
    )
    

    这可能是加载和设置导入并连接到 DOM 的相应 HTML/JS:

    <!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 工作室示例(点击构建并运行):https://webassembly.studio/?f=ff0fei4xgd9

    【讨论】:

      猜你喜欢
      • 2019-03-29
      • 2020-04-29
      • 1970-01-01
      • 1970-01-01
      • 2014-01-08
      • 2010-09-16
      • 1970-01-01
      • 2018-03-26
      • 2020-06-03
      相关资源
      最近更新 更多