
我给 div 绑定一个 click 事件,代码如下:
<div Onclick="click()"></div> <script> function click() { console.log('click') } </script> 单击触发 click 事件,运行结果如下:

我发现控制台没有任何的输出,第一时间我检查了一下代码,看上去好像没有任何问题呀。
突然想到, [难道 handle 函数的名字不能为 click ?] 我试着修改为 myclck,修改后代码如下:
<div Onclick="myclick()"></div> <script> function myclick() { console.log('click') } </script> 重新运行,结果如下:

居然真的可以,难道 handle 函数名不可以和事件名相同? js 中还有这样的规定? [心想,我 js 基础太差了吧]
我开始实验其他事件是不是也有相同的规定,所以我将 click 事件修改为 dblclick 事件,代码如下:
<div Ondblclick="dblclick()"></div> <script> function dblclick() { console.log('dblclick') } </script> 双击触发事件,结果如下:

居然可以 log 出来? [不是说好的 handle 函数名不能和事件名相同么?] 什么情况???
接下来我测试了 mousedown, mouseup, keyup, keydown, keypress 事件,都可以 log 出来,这就不上图了。
凭直觉, [应该只有 click 事件处理函数名不能为 click ] ,但这是为什么呢?
我加断点调试再次确定了没有执行 script 中的 click 处理函数。

我分析名为 click 的事件处理函数没有被调用的原因,难道是被覆盖了?
如果是这样的话,那么我应该可以 console.log(click) ,代码如下:
<div Onclick="console.log(click)"></div> 运行结果如下:

显而易见这样写是不可以的:
<div Onclick="myclick()"></div> <script> function myclick() { console.log(click) //ReferenceError: click is not defined } </script> [果然是本地函数 click 覆盖了名为 click 的处理函数] ,但是随意想想,什么情况?有全局 click 函数???
下面就是让我感到不解的地方。
第一:既然可以在 dom 元素中 Onclick="console.log(click)" ,并且没有类似于 window.Array === Array //true 等本地函数,因为 window.click //undefinded。那么这个 click 究竟被谁引用着?或者说为什么只有内联 js 才可以 console.log(click) 。
第二:我测试了下面的代码:
<div Onclick="console.log('click'); click()"></div> 运行结果如下:

难道执行了两次 onclick 中的代码?
试着再调用一次 click(),代码如下:
<div Onclick="console.log('click'); click(); click()"></div> 看出来了规律:

但是怎么解释这个运行结果?这也没有递归啊,js 引擎是怎么执行这段代码的?
希望大家可以解决这个问题!
环境:win10 + chrome
1 rabbbit 2019 年 4 月 21 日 <div Onclick="console.log(this.click === click);console.log(event.currentTarget.click === click)"></div> |
2 Mutoo 2019 年 4 月 21 日 我之前遇到过 <form Onsubmit="submit()"></form> 也遇到类似的问题。 在 onclick 这个 DOM Level 0 的事件侦听器上,存在一个默认的 With Block 作用域指向元素本身(这里的 this 即 div ),于是这里的 click 方法指向的是 div.click() (优先级更高)而不是 window.click() 如果你用 DOM Level 3 的事件侦听器:div.addEventListener('click', ...) 则不会有这个问题。 |
3 ayase252 2019 年 4 月 21 日 |
4 Biwood 2019 年 4 月 21 日 via Android 当使用 attribute 来绑定事件时,handler 的 this 指向元素本身,也就是 div 元素,所以 click()也相当于 div.click()。 为什么其他事件名不行?因为 div 是由 HTMLDivElement 接口实现的,而它又继承自 HTMLElement,click 属于该接口的一个 method,而 dbclick 则不是。 请参考 https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement#Methods |
8 kuanng OP 感谢大家的回复! |
9 meepo3927 2019 年 4 月 22 日 很涨姿势 |
10 buhi 2019 年 4 月 22 日 很偏门的姿势呢 学习了 |
11 longjiahui 2019 年 4 月 22 日 完全没试过直接用 click 命名的。 |
12 zhw2590582 2019 年 4 月 22 日 涨姿势了 |