addEventListener
和 onclick
有什么区别?
var h = document.getElementById("a");
h.onclick = dothing1;
h.addEventListener("click", dothing2);
上述代码位于单独的 .js
文件中,它们都能完美地工作。
addEventListener
和 onclick
有什么区别?
var h = document.getElementById("a");
h.onclick = dothing1;
h.addEventListener("click", dothing2);
上述代码位于单独的 .js
文件中,它们都能完美地工作。
domElement.addEventListener // Object(Method)
domElement.attributes.onload // Object(Property(Object(Property(String))))
有些变化,比如可以使用getter/setter来处理onload事件或者HashMap来处理属性,但最终看起来都是这样的。JavaScript消除了这层间接性,但需要知道其他方面的事情。它将domElement和属性合并在一起。
除非兼容性问题,否则应该按照最佳实践使用addEventListener。由于其他答案已经讨论了相关差异而不是基本的编程差异,所以我会放弃这个话题。实质上,在理想的情况下,你只需要从HTML中使用on*,但在更理想的情况下,你不应该在HTML中执行任何类似的操作。
为什么它如此占主导地位?因为它写起来更快,更容易学习,并且通常效果很好。
在HTML中,onload的整个目的就是提供对addEventListener方法或功能的访问权限。通过在JS中使用它,你可以直接应用它,而不是通过HTML间接应用它。
假设你可以自己创建属性:
$('[myclick]').each(function(i, v) {
v.addEventListener('click', function() {
eval(v.myclick); // eval($(v).attr('myclick'));
});
});
在处理此类问题时,JS的做法略有不同。
你可以将其类比为(对于每个创建的元素):
element.addEventListener('click', function() {
switch(typeof element.onclick) {
case 'string':eval(element.onclick);break;
case 'function':element.onclick();break;
}
});
具体的实现细节可能会有一些微小的差异,使得在某些情况下两者略有不同,但这就是要点。
可以说,将函数固定到on属性上是一种兼容性hack,因为默认情况下属性都是字符串。
// Function to change the content of t2
function modifyText() {
var t2 = document.getElementById("t2");
if (t2.firstChild.nodeValue == "three") {
t2.firstChild.nodeValue = "two";
} else {
t2.firstChild.nodeValue = "three";
}
}
// add event listener to table
var el = document.getElementById("outside");
el.addEventListener("click", modifyText, false);
onclick:
function initElement() {
var p = document.getElementById("foo");
// NOTE: showAlert(); or showAlert(param); will NOT work here.
// Must be a reference to a function name, not a function call.
p.onclick = showAlert;
};
function showAlert(event) {
alert("onclick Event detected!");
}
我想Chris Baker在他的优秀答案中已经总结得很好了,但是我想补充一下,使用addEventListener()时,您还可以使用options参数来更好地控制事件。例如-如果您只想运行事件一次,则可以在添加事件时使用{once:true}作为选项参数,以便仅调用它一次。
function greet() {
console.log("Hello");
}
document.querySelector("button").addEventListener('click', greet, { once: true })
以上函数只会打印一次“Hello”。 另外,如果你想清理你的事件,那么也有removeEventListener()选项。虽然使用addEventListener()有优点,但如果你的目标受众使用Internet Explorer,则该方法可能在某些情况下无法正常工作。你也可以在MDN上阅读关于addEventListener的内容,他们对如何使用它们给出了相当好的解释。
如果我们有一个监听器的引用,而且它不是匿名函数,那么我们还可以通过原型扩展监听器;或者让onclick
调用一个函数库(一个调用其他函数的函数)。
例如:
elm.onclick = myFunctionList;
function myFunctionList(){
myFunc1();
myFunc2();
}
onclick
调用,只需改变函数myFunctionList()
以实现任何想要的功能,但这会使我们失去冒泡/捕获阶段的控制,因此应避免在较新的浏览器中使用。addEventListener
方法更加安全。当然,您可以使用unsafe-inline
启用内联处理程序,但正如其名称所示,它不安全,因为它会带回整个JavaScript漏洞,而CSP则可以防止这些漏洞。/*
Testing that the function returned from bind is rereferenceable,
such that it can be added and removed as an event listener.
*/
function MyImportantCalloutToYou(message, otherMessage) {
// the following is necessary as calling bind again does
// not return the same function, so instead we replace the
// original function with the one bound to this instance
this.swap = this.swap.bind(this);
this.element = document.createElement('div');
this.element.addEventListener('click', this.swap, false);
document.body.appendChild(this.element);
}
MyImportantCalloutToYou.prototype = {
element: null,
swap: function() {
// now this function can be properly removed
this.element.removeEventListener('click', this.swap, false);
}
}
上述代码在Chrome中运行良好,可能有一些支架使"bind"与其他浏览器兼容。
addEventListener
可以设置多个处理程序,但不支持 IE8 或更低版本。
IE 有 attachEvent
,但并非完全相同。
onclick基本上是一个addEventListener,它在元素被点击时执行特定的函数。因此,当您有一个执行简单操作的按钮(如计算器按钮)时非常有用。 addEventlistener可以用于许多事情,例如在DOM或所有内容加载时执行操作,类似于window.onload但具有更多控制。
请注意,您实际上可以使用多个事件来进行内联,或者至少通过使用onclick将每个函数分隔开来使用分号,就像这样...
我不会使用内联编写函数,因为您可能以后会遇到问题,并且我认为这会很混乱。只需使用它来调用已在脚本文件中完成的函数即可。
我想要使用哪个取决于您想要什么。addEventListener用于复杂操作,onclick用于简单操作。我看过一些项目没有将特定的元素附加到元素上,而是实现了一个更全局的eventlistener,该eventlistener将确定是否在按钮上轻敲并根据按下的内容执行某些任务。在我看来,这可能会导致问题,并且尽管很小,但可能会浪费资源,如果该eventlistener必须处理每次单击。
'this'
关键字在 JavaScript 中所引用的上下文是不同的。
请看以下代码:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<input id="btnSubmit" type="button" value="Submit" />
<script>
function disable() {
this.disabled = true;
}
var btnSubmit = document.getElementById('btnSubmit');
btnSubmit.onclick = disable();
//btnSubmit.addEventListener('click', disable, false);
</script>
</body>
</html>
它的功能非常简单。当您点击按钮时,按钮将自动禁用。
首先,当您尝试以这种方式连接事件button.onclick = function()
时,单击按钮将触发onclick事件,但是按钮不会被禁用,因为button.onclick和onclick事件处理程序之间没有明确的绑定。如果您调试查看'this'
对象,您可以看到它引用'window'
对象。
其次,如果您注释掉btnSubmit.onclick = disable();
并取消注释//btnSubmit.addEventListener('click', disable, false);
,则可以看到按钮已被禁用,因为通过这种方式,button.onclick事件和onclick事件处理程序之间存在明确的绑定。如果您调试进入disable函数,您可以看到'this'
引用按钮控件
而不是window
。
这是我不喜欢JavaScript的一点,即不一致性。顺便说一句,如果您使用jQuery($('#btnSubmit').on('click', disable);
),它使用显式绑定。
btnSubmit.onclick = disable;
(赋值函数,不要调用它)。这样,在两种情况下,this
将引用按钮元素。 - Pasha