Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 带参数的事件侦听器_Javascript_Dom Events - Fatal编程技术网

Javascript 带参数的事件侦听器

Javascript 带参数的事件侦听器,javascript,dom-events,Javascript,Dom Events,我想用Javascript将参数传递给事件侦听器。 我已经找到了解决方案,但我无法理解它们为什么或如何工作,以及为什么其他解决方案不起作用 我有C/C++的背景,但是在Javascript中,函数的执行有很大不同。 您能帮助我理解以下示例是如何工作的以及为什么不工作的吗 如果没有参数,代码工作正常: var clicker = document.getElementById("mainNavToggle"); clicker.addEventListener("click", eventFunc

我想用Javascript将参数传递给事件侦听器。 我已经找到了解决方案,但我无法理解它们为什么或如何工作,以及为什么其他解决方案不起作用

我有C/C++的背景,但是在Javascript中,函数的执行有很大不同。 您能帮助我理解以下示例是如何工作的以及为什么不工作的吗

如果没有参数,代码工作正常:

var clicker = document.getElementById("mainNavToggle");
clicker.addEventListener("click", eventFunction);

function eventFunction()
{
  console.log("works");
}
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) 
  };
}

如果在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);

function eventFunction()
{
  console.log("works");
}
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,否则就不需要传递参数

我注意到的第一件事是没有调用这个eventFunction 立刻

它会立即被调用。但是,它返回一个新函数。这是为单击处理程序注册的函数。调用此函数时,将在闭包中调用函数
func
。传递给此函数的参数也保存在闭包中


要理解这个概念,您需要了解闭包是如何工作的。这是一个已经被广泛讨论过的话题,所以我将向您指出。

让我们一步一步地剖析这个话题

一般信息

.addEventListener
函数/方法接受2(或3)个参数:

  • 一个
    字符串
    ,其值为事件类型/名称(例如
    “单击”
  • 指向
    函数的指针,该函数应在事件发生时执行
  • 一个
    布尔值
    ,指定是否应使用事件冒泡或事件传播。此参数是可选的,可以省略
示例1

在第一个示例中,您将
字符串
“单击”
)和指向
函数
事件函数
)的指针传递到
。addEventListener
。一切正常,事件发生,函数执行

示例2

在本例中,您将
字符串
未定义的
传递给
.addEventListener
,这不是
.addEventListener
所期望的。您可能会问自己“我什么时候传入了
未定义的
?”。嗯,当您通过在它之后添加parens
()
来执行
eventFunction
时,它就发生了。在这里,JS中的语法与大多数其他语言中的语法相同,在函数右侧添加paren将执行函数

由于
eventFunction
没有显式返回任何内容,因此它会自动返回
undefined
。因此,这就是
.addEventListener
得到的:

clicker.addEventListener("click", undefined)
但是,由于您执行了
eventFunction
,它会将
“it worked”
记录到控制台一次

示例3

此示例失败的原因与示例2失败的原因相同

示例4

上一个示例中的代码是有效的,因为它使用了一个称为闭包的概念。对于这个概念有成千上万的解释,所以我在这里的解释将非常简短。如果你理解它有困难,只需谷歌搜索 “javascript闭包”

与许多其他语言相比,JavaScript具有函数作用域而不是块作用域。因此,如果在函数
F
中定义一个变量,并从
F
中返回另一个函数
G
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';
编辑:解决问题

下面是一个工作示例,请注意,我更改了函数名称以反映其用途:

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

我倾向于说这个问题是不同的,因为它问的更多的是“为什么”,而另一个问题的重点是“如何”。问这个问题的人已经知道该如何回答了@GeorgeJemptythan感谢您的详细解释。因此,在函数eventFunc中,我们返回一个指向匿名函数的指针,该匿名函数接受一个参数(事件),并执行func函数,该函数由于闭包而可以访问myStr字符串。按照您的逻辑,我认为如果我直接返回一个指向func的指针,而不是指向调用func的未定义函数的指针,可能会起作用。所以我尝试了
functioneventfunction(myStr){functionfunc(event,myStr){console.log(myStr);}returnfunc(event,myStr);}
继续。。我现在得到的输出是事件对象,就好像函数func包含
console.log(event)
why is?.conitnuing一样。经过一番思考,我认为这与eventlistener所期望的函数指针类型有关。它是否只需要一个参数函数指针,而该参数始终是