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

tec*_*ant 1 javascript events return addeventlistener

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

据我所知,问题来自于return.

原始HTML

<section id="titles" ondrop="dropClip(this, event)" ondragenter="return false" ondragover="return false"></section>
Run Code Online (Sandbox Code Playgroud)

期望的HTML

<section id="titles"></section>
Run Code Online (Sandbox Code Playgroud)

JavaScript的

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

titles
    .addEventListener('drop', dropClip(this, event))
    .addEventListener('dragenter', return false)
    .addEventListener('dragover', return false);
Run Code Online (Sandbox Code Playgroud)

Eri*_*ikE 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
};
Run Code Online (Sandbox Code Playgroud)

(实际上,第一个将最终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`
Run Code Online (Sandbox Code Playgroud)

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

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

但回头一看我们的赋值语句制作a,b以及c所有为的别名myfun功能:在这种情况下,我们没有使用括号,因为- 这里是它变得非常重要,所以要注意:

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

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

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

var a = myfun(), b = myfun(), c = myfun();
Run Code Online (Sandbox Code Playgroud)

a,b并且c将不再是该myfun函数的指针.他们都将是结果,myfun并将包含任何myfun返回 - 或者undefined如果它没有返回任何东西.如果您尝试调用其中一个,请说a()您会收到类似于以下内容的错误:

> TypeError: a is not a function
Run Code Online (Sandbox Code Playgroud)

现在我已经绘制了所有背景知识,有一个简单的事情可以让你顺利通过以下方面addEventListener:它需要一个函数作为第二个参数.在您的示例代码中,您在addEventListener调用它们时放置了您想要运行的函数的内容,但没有实际的函数.

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

function doNothing() {
   return false;
}

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

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

这看起来像这样:

titles.addEventListener('dragenter', function () { // anonymous function
    return false;
});
Run Code Online (Sandbox Code Playgroud)

如果你想调用一个匿名函数,你必须让javascript知道你想把它当作一个值来对待它,而不是在当前作用域中创建一个命名函数的常规快捷方法(在这里function myfun被视为var myfun = function).这是通过将整个事物包装在另外一组括号中来完成的,如下所示:

(function () { // begin a function value containing an anonymous function
    // do something
}()); //invoke it, and close the function value
Run Code Online (Sandbox Code Playgroud)

我希望这有助于您更多地了解javascript,为什么代码无法正常工作,以及您需要做些什么来使其工作.