我想将参数传递给Java事件监听器。 我找到了解决方案,但是我不明白它们为什么起作用或如何起作用以及为什么其他解决方案不起作用。
我有C / C ++背景,但是在Javascript函数中执行的功能却大不相同。 您能否帮助我理解以下示例的工作方式和原因,以及为什么不起作用?
没有参数的代码可以正常工作:
var clicker = document.getElementById("mainNavToggle");
clicker.addEventListener("click", eventFunction);
function eventFunction()
{
console.log("works");
}
如果我在eventListener上包括方括号,该函数将执行一次而不会触发事件,然后不执行任何操作:
var clicker = document.getElementById("mainNavToggle");
clicker.addEventListener("click", eventFunction());
function eventFunction()
{
console.log("works");
}
我想这是因为该函数是在eventListener上调用的,因此不允许eventListener函数稍后再调用eventFunction。
当我想使用eventFunction传递参数时。 以下内容不起作用:
var clicker = document.getElementById("mainNavToggle");
clicker.addEventListener("click", eventFunction("works"));
function eventFunction(myStr)
{
console.log(myStr);
}
它调用eventFunction而不触发事件,然后在触发事件时不执行任何操作,这与以前的行为相同。 到目前为止,我认为我能理解。
为了在事件函数中正确传递参数,我找到了以下代码。 以下解决方案可以正常工作:
var clicker = document.getElementById("mainNavToggle");
clicker.addEventListener("click", eventFunction("works"));
function eventFunction(myStr)
{
function func(event, myStr)
{
console.log(myStr);
}
return function(event) {
func(event,myStr)
};
}
我注意到的第一件事是未立即调用此eventFunction。 为什么会这样?
但是,我不知道如何在每个函数中传递参数。 我知道“ works”字面量会传递给eventFunction上的myStr。 但是在func函数中,eventFunction没有传递附加的事件参数。
为什么eventFunction需要返回另一个带有内部调用func函数的参数的函数?
还请注意,我想将参数传递给没有全局作用域的eventFunction,否则将不需要传递参数。
答案 0 :(得分:1)
让我们逐步剖析。
常规信息
.addEventListener
函数/方法采用2(或3)个参数:
String
,其值为事件类型/名称(例如"click"
)Function
的指针,该指针应在事件发生时执行Boolean
,指定是否应使用事件冒泡或事件传播。此参数是可选的,可以省略。示例1
在您的第一个示例中,您将String
("click"
)和指针指向Function
(eventFunction
)到{{ 1}}。一切都按预期进行,事件发生并执行了功能。
示例2
在此示例中,您将.addEventListener
和String
传递给undefined
,这不是.addEventListener
所期望的。您可能会问自己“ 我何时传递.addEventListener
?”。好吧,只要您在undefined
之后加上括号eventFunction
,就执行了它们。在这里,JS中的语法与大多数其他语言中的语法相同,在函数右侧添加括号以执行该函数。
由于您的()
没有明确返回任何内容,因此它会自动返回eventFunction
。因此,undefined
就是这样的:
.addEventListener
但是,由于您执行了clicker.addEventListener("click", undefined)
,因此它将eventFunction
记录到控制台一次。
示例3
此示例由于与示例2失败相同的原因而失败。
示例4
最后一个示例中的代码有效,因为它使用了称为闭包的概念。实际上有数千个关于此概念的解释,因此我在这里的解释将非常简短。如果您在理解它时遇到困难,请通过google “ javascript闭包”。
与许多其他语言相比,JavaScript具有功能作用域而不是块作用域。因此,如果您在函数"It worked"
中定义变量并从F
内部返回另一个函数G
,则F
可以从{{ 1}} 。出于演示目的:
G
将此简短示例与您的第四个代码进行比较:它们几乎相同。唯一的区别是,您的代码创建了一个额外的功能F
。
现在,如果您致电function F () {
var fVariable = 'Defined in F';
return function G () {
return fVariable; // <-- this is the closure
}
}
var funcG = F(); // <-- execute F
funcG(); // -> 'Defined in F';
,
您执行func
,将返回另一个(匿名/ lambda)函数,该函数通过闭包封装clicker.addEventListener("click", eventFunction("it works"))
字符串。如果我们手动将其写出,这就是eventFunction
所看到的:
"it works"
编辑:解决问题
这是一个工作示例,请注意,我更改了函数名称以反映其用途:
.addEventListener
clicker.addEventListener("click", function (event) {
func("it works", event);
});
函数返回一个函数function eventHandlerFactory (myStr) { // <-- eventFunction in your code
return function executeOnEvent (event) { // <-- executed if an event occurs
console.log(myStr);
console.log(event);
}
}
clicker.addEventListener("click", eventHandlerFactory("it worked"));
,该函数将传递到eventHandlerFactory
中。再次手动将其写出,这就是解释器的理解:
executeOnEvent
答案 1 :(得分:0)
我注意到的第一件事是未调用此eventFunction 立即
它立即被调用。但是,它返回一个新函数。这是为单击处理程序注册的功能。调用此函数时,将在闭包中调用函数func
。传递给该函数的参数也保留在闭包中。
要理解此概念,您需要了解闭包是如何工作的。这是一个广泛讨论的主题,所以我只将您引向How do JavaScript closures work?。