Golang中如何解决无法向js.Func传递参数的问题

Golang中如何解决无法向js.Func传递参数的问题 以下代码中,函数已正确附加到按钮的 onclick 事件:

func f(this js.Value, args []js.Value) interface{} {
	println("hello world")
	return nil
}
btn.Set("onclick", js.FuncOf(f))

我尝试为这个函数传递参数,如下所示:

btn.Set("onclick", js.FuncOf(f).Invoke("Hello World"))

并在 js.Func 中处理这些参数:

	for x := range args {
		println(x)
	}

但我遇到了以下错误:

wasm_exec.js:421 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'exports')
    at syscall/js.valueInvoke (wasm_exec.js:421)
    at syscall_js.valueInvoke (main.wasm:0x133521)
    at syscall_js.Value.Invoke (main.wasm:0x131300)
    at main.html (main.wasm:0x25b572)
    at main.main (main.wasm:0x25e591)
    at runtime.main (main.wasm:0x7f285)
    at wasm_pc_f_loop (main.wasm:0xddf81)
    at wasm_export_run (main.wasm:0xddf54)
    at global.Go.run (wasm_exec.js:577)
    at init (wasm.js:7)

有什么想法吗?


更多关于Golang中如何解决无法向js.Func传递参数的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

我通过使用 .bind 解决了这个问题,如下所示:

element.Set("onclick", js.FuncOf(f).Call("bind", e, args...)) 
// bind(event, arguments...),传递给函数 f 的参数为 (arguments..., event)

因此,我的代码变为:

btn.Set("onclick", js.FuncOf(f).Call("bind", btn, "hi", "hello"))

func f(this js.Value, args []js.Value) interface{} {
	for index, item := range args {
		if x < len(args)-1 { // len(args)-1 是事件本身
			println(index, item.String())
		}
	}

	self := args[len(args)-1].Get("target")
	// self = event.target == this
	self.Get("style").Call("setProperty", "background-color", "red")
    // 等同于:
	// this.Get("style").Call("setProperty", "background-color", "red")
	return nil
}

更多关于Golang中如何解决无法向js.Func传递参数的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go WebAssembly中,js.FuncOf创建的JavaScript函数不能直接通过Invoke传递参数给事件处理器。事件处理器会自动接收事件对象作为参数。以下是正确的实现方式:

package main

import (
	"syscall/js"
)

func main() {
	// 获取按钮元素
	btn := js.Global().Get("document").Call("getElementById", "myButton")
	
	// 创建带参数处理的函数
	f := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
		// 第一个参数是事件对象
		event := args[0]
		
		// 传递自定义参数的方式
		message := "Hello World"
		println("Received message:", message)
		
		// 访问事件属性
		target := event.Get("target")
		println("Button ID:", target.Get("id").String())
		
		return nil
	})
	
	// 直接附加函数,不要调用Invoke
	btn.Set("onclick", f)
	
	// 保持程序运行
	select {}
}

如果需要传递动态参数,可以使用闭包:

func createClickHandler(param string) js.Func {
	return js.FuncOf(func(this js.Value, args []js.Value) interface{} {
		println("Parameter from closure:", param)
		
		// 仍然可以访问事件对象
		if len(args) > 0 {
			event := args[0]
			println("Event type:", event.Get("type").String())
		}
		
		return nil
	})
}

// 使用方式
btn.Set("onclick", createClickHandler("Custom Parameter"))

或者使用元素的数据属性:

// Go代码
f := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
	btn := args[0].Get("target")
	param := btn.Get("dataset").Get("myParam").String()
	println("Data parameter:", param)
	return nil
})

// HTML中
// <button id="myButton" data-my-param="valueFromHTML">Click</button>

错误的原因是你试图在Go端调用Invoke,这会在WebAssembly模块初始化完成前执行。事件处理器应该直接设置为js.Func对象,JavaScript运行时会在事件触发时自动调用它并传递事件参数。

回到顶部