我给 div 绑定一个 click 事件,代码如下:
<div onclick="click()"></div>
<script>
function click() {
console.log('click')
}
</script>
单击触发 click 事件,运行结果如下:
我发现控制台没有任何的输出,第一时间我检查了一下代码,看上去好像没有任何问题呀。
突然想到, [难道 handle 函数的名字不能为 click ?] 我试着修改为 myclick,修改后代码如下:
<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-04-21 19:12:36 +08:00
<div onclick="console.log(this.click === click);console.log(event.currentTarget.click === click)"></div>
|
2
Mutoo 2019-04-21 19:15:35 +08:00 3
我之前遇到过 <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-04-21 19:27:18 +08:00 1
|
4
Biwood 2019-04-21 19:34:28 +08:00 via Android 4
当使用 attribute 来绑定事件时,handler 的 this 指向元素本身,也就是 div 元素,所以 click()也相当于 div.click()。
为什么其他事件名不行?因为 div 是由 HTMLDivElement 接口实现的,而它又继承自 HTMLElement,click 属于该接口的一个 method,而 dblclick 则不是。 请参考 https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement#Methods |
7
Biwood 2019-04-21 20:13:06 +08:00 via Android 1
@kuanng 浏览器的安全策略,第二轮递归中的 div.click 不是由人类行为直接触发,会被浏览器阻止。
|
8
kuanng OP 感谢大家的回复!
|
9
meepo3927 2019-04-22 11:23:23 +08:00
很涨姿势
|
10
buhi 2019-04-22 11:32:05 +08:00
很偏门的姿势呢 学习了
|
11
longjiahui 2019-04-22 13:59:23 +08:00
完全没试过直接用 click 命名的。 🧱
|
12
zhw2590582 2019-04-22 14:37:11 +08:00
涨姿势了
|