Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/362.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 eventhandler:获取参数的处理程序的执行出现问题_Javascript_Events_Javascript Events - Fatal编程技术网

Javascript eventhandler:获取参数的处理程序的执行出现问题

Javascript eventhandler:获取参数的处理程序的执行出现问题,javascript,events,javascript-events,Javascript,Events,Javascript Events,我遇到了这个问题: 我定义了一个需要参数的事件处理程序 var handler = function(p1, p2){ //some code } 然后我将事件处理程序添加到函数内的对象中 function foo(p1, p2){ //Some code obj.addEventListener('click', handler(p1, p2), false) } 正如您已经知道的,上面的代码是不正确的。它不会听这个事件。相反,它将立即执行该函数。现在要解决这个问题

我遇到了这个问题:

我定义了一个需要参数的事件处理程序

var handler = function(p1, p2){
    //some code
}
然后我将事件处理程序添加到函数内的对象中

function foo(p1, p2){
    //Some code
    obj.addEventListener('click', handler(p1, p2), false)
}
正如您已经知道的,上面的代码是不正确的。它不会听这个事件。相反,它将立即执行该函数。现在要解决这个问题,我可以删除
处理程序(p1,p2)
并插入
function(){handler(p1,p2)}
。但问题是,我还有一个函数要删除事件侦听器,这在后一种解决方案中是不可能的

function koo(){
    //Some code
    obj.removeEventListener('click', handler, false)
}
我该如何解决这个问题呢?

不就是这样吗:

function foo(){
    //Some code
    obj.addEventListener('click', handler, false)
}

传递函数而不是调用它。

我认为您不想在那里传递参数,因为这是一个回调,您永远不知道这些变量是什么

你能做

(function() {

   var p1 = 'a',
       p2 = 'b',
       obj = document.getElementById('my-object');

   var handleClick = function(event) {
      // Access to p1 and p2
      // Access to `event` object containing info about the event
   }

   obj.addEventListener('click', handleClick, false);

   // If you want to remove it
   obj.removeEventListener('click', handleClick, false);

})();

我可以问一下你为什么要争论这个问题吗?您是否也打算以非点击触发方式调用它?

我认为您需要创建一个闭包:

var createHandler = function(p1, p2){
    return function (event) {
        //some code that uses p1 and p2
    };
};

var handler;
…现在您可以这样分配处理程序,同时仍然可以访问p1和p2:

function foo(p1, p2){
    handler = createHandler(p1, p2);
    //Some code
    obj.addEventListener('click', handler, false);
}

function koo(){
    //Some code
    obj.removeEventListener('click', handler, false);
    handler = null;
}
请注意,
handler
现在是一个全局变量


更新:我刚刚意识到,在您的情况下,可以通过合并
createHandler
foo
来简化此过程,如下所示:

var handler; // we need this to be accessible both to foo and koo

function foo(p1, p2){
    handler = function(event) {
        // some code that uses p1 and p2
    };
    //Some code
    obj.addEventListener('click', handler, false);
}

function koo(){
    //Some code
    obj.removeEventListener('click', handler, false);
    handler = null;
}

澄清一下:当您将侦听器设置为
handler(p1,p2)
时,您正在使用两个参数调用
handler
p1
p2
)它返回的值并将其分配给事件,而不是将函数
handler
指定为您明确想要的侦听器。这只会传递一个
event
参数,不是吗(不是
p1
p2
)?参数呢?p1和p2也需要传递,这就是问题所在,您是只对一个元素还是对几个元素执行此操作?
foo
koo
在哪个范围内活动?
koo
如何知道要删除哪个处理程序?很抱歉,我这么做是为了几个元素,如果我理解正确,foo和koo是在全局范围内定义的,而不是在任何其他函数内定义的。除koo之外,还有其他几个函数删除了事件处理程序。你能解释一下´(function(){//some code}()')的作用吗?我以前从未见过这一点?你不是忘了结尾的“')吗?你必须把
var handleClick
赋值放在
addEventListener
之前。否则,
handleClick
将是
未定义的
@Woho87:是的,他有,这是一个即时函数
function(){…}
是定义,
()
立即执行函数。这是用来创建privat作用域的。@Woho87谢谢,修复了。费利克斯说什么……:)顺便说一句,另一个选项是使用函数定义,即只需
函数handleClick(){…}
,然后您可以按任意顺序放置它们。但是如果你使用变量,在代码中给变量赋值之前,变量是未定义的。我现在已经测试过了。问题是var handler=createHandler(p1,p2);必须在函数foo中定义才能工作。外面没用。但是,如果它不在外部,我就不能删除事件侦听器,所以同样的问题就放在
var处理程序中
foo
函数之外(从而创建一个全局变量)。我已经更新了答案。没问题(谢谢你的代表分数;-)。顺便说一句,我刚刚意识到它可以简化一点,请参阅更新的答案。@Woho87:这对你有用吗?这就是我提出这个问题的原因:如果你总是在
foo
之后调用
koo
,效果会很好。但是,只要调用
foo
两次,就会丢失对首先创建的处理程序的引用,并且无法删除它。目前的代码只支持创建和删除一个处理程序。。。