从GO WebAssembly调用JavaScript事件

huangapple go评论114阅读模式
英文:

Calling JavaScript event from GO WebAssembly

问题

在JavaScript中,事件非常常见,可以通过以下方式调用:

  1. <p id="p_id">
  2. </p><button id="some_id">Click me</button>
  3. var element=document.querySelector("#some_id")
  4. var listener=element.addEventListener('click',function(event){
  5. document.querySelector("#p_id").innerHTML = "Hello World";
  6. });
  7. // 或者
  8. <p id="p_id">
  9. <button onclick="some_function()">Click me</button>
  10. <script>
  11. function some_function() {
  12. document.querySelector("#p_id").innerHTML = "Hello World";
  13. }

我知道在GO中,可以使用js.Global().Get().Call()js.Global().Get().Invoke()来调用典型的JS函数,如下所示:

  1. //go:build js && wasm
  2. package main
  3. import (
  4. "syscall/js"
  5. )
  6. var (
  7. document js.Value
  8. )
  9. func init() {
  10. document = js.Global().Get("document")
  11. }
  12. func main() {
  13. c := make(chan int) // channel to keep the wasm running, it is not a library as in rust/c/c++, so we need to keep the binary running
  14. alert := js.Global().Get("alert")
  15. alert.Invoke("Hi")
  16. h1 := document.Call("createElement", "h1")
  17. h1.Set("innerText", "This is H1")
  18. h1.Get("style").Call("setProperty", "background-color", "blue")
  19. <-c
  20. }

要在GO中添加eventListner,可以按照以下方式进行:

  1. var cb js.Func
  2. cb = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
  3. fmt.Println("button clicked")
  4. cb.Release() // release the function if the button will not be clicked again
  5. return nil
  6. })
  7. js.Global().Get("document").Call("getElementById", "myButton").Call("addEventListener", "click", cb)

我正在寻找的是,如何在GO中对由JavaScript触发的事件进行响应。

更新

总结一下,我如何编写一个go代码来完成下面的JavaScript代码所做的事情(使用IndexedDB API):

  1. function remove() {
  2. var request = db.transaction(["employee"], "readwrite")
  3. .objectStore("employee")
  4. .delete("00-03");
  5. request.onsuccess = function(event) {
  6. alert("Kenny's entry has been removed from your database.");
  7. };
  8. }

有什么想法吗?

英文:

In JavaScript events are vey common that can be called as:

  1. <p id="p_id">
  2. </p><button id="some_id">Click me</button>
  3. var element=document.querySelector("#some_id")
  4. var listener=element.addEventListener('click',function(event){
  5. document.querySelector("#p_id").innerHTML = "Hello World";
  6. });
  7. // OR
  8. <p id="p_id">
  9. <button onclick="some_function()">Click me</button>
  10. <script>
  11. function some_function() {
  12. document.querySelector("#p_id").innerHTML = "Hello World";
  13. }

I aware with typical JS functions, we can use js.Global().Get().Call() and js.Global().Get().Invoke() in GO, as:

  1. //go:build js && wasm
  2. package main
  3. import (
  4. "syscall/js"
  5. )
  6. var (
  7. document js.Value
  8. )
  9. func init() {
  10. document = js.Global().Get("document")
  11. }
  12. func main() {
  13. c := make(chan int) // channel to keep the wasm running, it is not a library as in rust/c/c++, so we need to keep the binary running
  14. alert := js.Global().Get("alert")
  15. alert.Invoke("Hi")
  16. h1 := document.Call("createElement", "h1")
  17. h1.Set("innerText", "This is H1")
  18. h1.Get("style").Call("setProperty", "background-color", "blue")
  19. <-c
  20. }

To add eventListner from GO, I know we can do it as:

  1. var cb js.Func
  2. cb = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
  3. fmt.Println("button clicked")
  4. cb.Release() // release the function if the button will not be clicked again
  5. return nil
  6. })
  7. js.Global().Get("document").Call("getElementById", "myButton").Call("addEventListener", "click", cb)

What I'm looking for, is how to response from GO to the even that is triggered in JavaScript.

UPDATE

To wrap up, how can I write a go code to do the same of the JavaScript code below (Which is using IndexedDB API):

  1. function remove() {
  2. var request = db.transaction(["employee"], "readwrite")
  3. .objectStore("employee")
  4. .delete("00-03");
  5. request.onsuccess = function(event) {
  6. alert("Kenny's entry has been removed from your database.");
  7. };
  8. }

Any thought?

答案1

得分: 1

如果你的事件是一个可归因的变量(例如 request.onsuccess = function() { ... }),你可以使用 Set 来定义一个 js.FuncOf,以处理结果,就像处理一个 JavaScript 函数一样,类似于:

  1. req := js.Global().Get("db").Call("transaction").Call("objectStore").Call("delete")
  2. var f js.Func
  3. f = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
  4. defer f.Release()
  5. js.Global().Call("alert", "Kenny's entry has been removed from your database.")
  6. return nil
  7. })
  8. req.Set("onsuccess", f)

别忘了在完成后释放函数(Release);)

英文:

If your even is an attributable variable (e.g. request.onsuccess = function() { ... }) you can use Set to define a js.FuncOf to handle the result as a javascript function would, something like:

  1. req := js.Global().Get("db").Call("transaction").Call("objectStore").Call("delete")
  2. var f js.Func
  3. f = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
  4. defer f.Release()
  5. js.Global().Call("alert", "Kenny's entry has been removed from your database.")
  6. return nil
  7. })
  8. req.Set("onsuccess", f)

Don't forget to Release the function once you're done 从GO WebAssembly调用JavaScript事件

huangapple
  • 本文由 发表于 2021年11月15日 18:35:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/69972999.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定