javascript - 引号中的 JavaScript onclick 处理程序给出不同的行为?
问题描述
我今天在编写一些演示代码时注意到了这种奇怪的行为,我很好奇发生了什么。尽管“Button 2”可以,但“Button”不起作用,即使它们的设置方式不同。我知道这与引用有关,但我很好奇为什么会这样。同样,如果我在引号中将函数传递给按钮 3,而不是将其直接附加到按钮 4 中,则按钮 4 有效,但按钮 3 无效。
另外,我认为鉴于按钮 2 有效,它会console.log("test")
立即进行评估(类似于没有引号的情况),而是延迟到实际单击按钮。我知道这不是最好的方法,但出于好奇,我很好奇这里到底发生了什么。
document.getElementById("app").innerHTML = `
<h1>Testing Sandbox</h1>
<div>
<button id='hello'>Button</button>
<button id='hello2' onclick='console.log("test")'>Button 2</button>
<button id='hello3' onclick='(e) => console.log("test")'>Button 3</button>
<button id='hello4'>Button 4</button>
</div>
`;
document.getElementById("hello").onclick = 'console.log("test")';
document.getElementById("hello4").onclick = (e) => console.log("test");
<!DOCTYPE html>
<html>
<head>
<title>Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<div id="app"></div>
<script src="src/index.js">
</script>
</body>
</html>
解决方案
当你分配给 时,你调用了一个 setter,它做的事情与使用分配的表达式onclick
调用非常相似。addEventListener
但是如果传递的表达式不是函数,两者addEventListener
和都会默默地失败:onclick
document.getElementById("app").innerHTML = `
<h1>Testing Sandbox</h1>
<div>
<button id='hello'>Button</button>
`;
document.getElementById("hello").onclick = 'console.log("test")';
// nearly the same thing as:
document.getElementById("hello").addEventListener('click', 'console.log("test")');
<div id="app"></div>
该字符串不会被隐式强制转换为函数。
在第三个示例中,内联处理程序声明了一个函数,但从不执行它:
<button id='hello3' onclick='(e) => console.log("test")'>Button 3</button>
这就像
button.addEventListener('click', function(event) {
(e) => console.log("test")
});
侦听器运行,但侦听器不包含除未使用的函数表达式以外的任何内容,因此单击时您看不到任何内容。如果您添加日志语句,这可能会更清楚:
<button id='hello3' onclick='console.log("listener running;"); (e) => console.log("test")'>Button 3</button>
一般来说,你不应该使用内联处理程序;它们需要全局污染,难以管理,存在字符串和 HTML 转义问题,并且几乎被普遍认为是不好的做法。相反,使用addEventListener
并始终传递函数而不是字符串,以便正确添加侦听器。
推荐阅读
- typescript - Typescript:至少实现一个特定接口的类
- javascript - How to handle dynamic image paths with webpack
- javascript - JavaScript Uglify 不同且正确?
- android - 如果使用 FLAG_LAYOUT_NO_LIMITS,则无法使用 setStatusBarColor 设置状态栏颜色
- c - 用于变量属性的 GCC 扩展 __attribute__ ((未使用))
- javascript - Bootstrap Twitter输入类型文件如何清除文件?
- python - 生产环境中如何处理tqdm/tqdm_notebook
- r - 在 r 中进行 polr 总结时出错
- glfw - 带有glfw的简单opengl三角形程序呈现黑屏
- javascript - 如何在 Node.js 中获取目录项的数量