在javascript中向元素添加多个事件侦听器

时间:2013-04-01 22:39:44

标签: javascript events return addeventlistener

我有一个小的拖放设置并运行,但它使用内联javascript,我更喜欢将它全部移动到外部文件。从理论上讲,这是一个简单的交换,但我在检查员中得到了referenceErrors并且我的minifcation失败了。

据我所知,问题来自return

原始HTML

<section id="titles" ondrop="dropClip(this, event)" ondragenter="return false" ondragover="return false"></section>

所需的HTML

<section id="titles"></section>

的JavaScript

var titles = document.getElementById('titles');

titles
    .addEventListener('drop', dropClip(this, event))
    .addEventListener('dragenter', return false)
    .addEventListener('dragover', return false);

2 个答案:

答案 0 :(得分:9)

Javascript是一种函数是“一流对象”的语言。这意味着,可能与您可能遇到过的其他编程语言相反,您可以将函数视为任何其他对象:您可以传递它,您可以返回它,您可以在其中使用带有函数的函数其中的功能,等等。

这可能是在Javascript中成功所需的非常意外的编程风格。在其他语言中,UI事件绑定以多种方式发生(例如C#的Button1.Click += new System.EventHandler(this.myEventHandler);或Classic VB的Button_Click())。在C#中,您可以传递委托,这些委托是具有特定定义的参数和返回值的特殊对象,函数可以绑定到该委托。但是所有这些都在javascript中消失了,因为您可以直接将函数附加到属性 。对于浏览器DOM事件处理,该属性被假定为函数引用,并且在该事件的本机事件处理代码期间,它调用附加到该属性的函数,其名称与事件相同。

好的,你说,我们有功能。我们可以传递它们并像变量一样处理它们。现在怎么样?

首先,请特别注意以下两个函数声明相同。它们产生完全相同的结果,在当前作用域中声明了一个名为myfun的函数(在浏览器中,window对象或正在运行的当前函数。)

function myfun(param1, param2) {
   //do some stuff
};

var myfun = function (param1, param2) {
   //do some stuff
};

实际上,第一个属性将以name属性结束,第二个属性不会,可能还有其他一些细微差别,但是对于所有实际意图和目的,它们是相同的)。

第一个只是第二个的捷径。基本上,您创建一个函数(可能有也可能没有名称)并将其分配给变量。程序员使用方便的快捷方式调用结果“myfun函数”,但实际上案例是“myfun变量 - 它现在包含一个特定的函数”。

只需将其分配给其他变量,就可以获得对同一函数的多个引用 - 这是一个真正的对象:

function myfun(param1, param2) {
   //do some stuff
};

var a = myfun, b = myfun, c = myfun;

a(); // runs `myfun`
b(); // runs `myfun`
c(); // runs `myfun`

接下来需要注意的是,要调用函数,必须在其名称后面使用括号,并且所有参数都在括号内。

var result = myfun('a', 1); // invoke the `myfun` function
   // and store its return value in variable `result`

但回顾一下我们的作业声明,使abc都成为myfun函数的别名:在这些情况下,我们没有使用括号,因为 - ,这里它变得非常重要,所以要注意

  

调用函数(并获取函数的返回值),请在其名称后面使用括号。

     

要传递函数引用,请不要使用括号。

如果我们这样做了怎么办:

var a = myfun(), b = myfun(), c = myfun();

abc将不再是myfun函数的指针。它们都是myfun结果,并且包含返回的myfun - 或undefined如果它没有返回任何内容。如果你试图调用其中一个,比如a(),你会得到类似于:

的错误
> TypeError: a is not a function

现在我已经绘制了所有背景知识,有一件简单的事情可以让你跟上addEventListener的成功:它期望一个函数作为第二个参数。在您的示例代码中,您在addEventListener调用它们时放置了您想要运行的函数的内容,但没有实际的函数。

您可以通过首先实际声明函数来解决这个问题,例如:

function doNothing() {
   return false;
}

titles.addEventListener('dragenter', doNothing);
   // Note: this is not invocation like `doNothing()`, but passing a reference

或者,您可以将函数语句简单地包装到匿名函数中。请记住,javascript中的函数实际上没有名称,我们只有包含函数的变量。匿名函数是一个根本没有名称的函数,它可以通过隐式名称赋值(例如作为参数传递 - 它将具有参数的名称)或通过执行魔术调用直接调用来调用。把括号放在后面的动作。

这看起来像这样:

titles.addEventListener('dragenter', function () { // anonymous function
    return false;
});

如果要调用匿名函数,则必须让javascript知道您希望将其视为值,而不是在当前范围内创建命名函数的常规快捷方法(其中{{1}被视为function myfun)。这是通过将整个事物包装在一组括号中来完成的,如下所示:

var myfun = function

我希望这有助于您了解有关javascript的更多信息,为什么代码无法正常工作以及您需要做些什么才能使其正常工作。

答案 1 :(得分:0)

当然,您必须将您提供给addEventListener的函数内容包装到函数中。

例如,您将代替.addEventListener('drop', dropClip(this, event))撰写.addEventListener('drop', function(event) { dropClip(this, event); })