问题
今天突然要维护一个老古董的项目,里面大部分都是原生js和jquery,用vue之类多了,这些都有些生疏... 代码中有一个HTML事件处理程序,<button onclick="clickHandler(e)">屠龙宝刀点击就送</button>
function clickHandler(e) {
console.log(e.target);
}
刚开始都没注意有啥错,然后在函数中e.target
等都会报错:ReferenceError: e is not defined
很明显,传入的事件对象参数是错误的,在HTML事件处理程序的情况下正确的做法是传入完整的event名称,<button onclick="clickHandler(event)">屠龙宝刀点击就送</button>
其实event
可以看作是window.event
的简写,用window对象的其他属性试验下就可以发现,比如用location
,<button onclick="clickHandler(location)">屠龙宝刀点击就送</button>
, 那么函数中e.href
即可打印出当前链接。
function clickHandler(e) {
console.log(e.href);
}
思考
其实上面本来不是个问题,主要平时很少用行内的HTML事件处理程序,所以随手把参数event
写错为了e
。在DOM0和DOM2级事件处理程序中,浏览器都会将一个event
对象传入到事件处理程序中,这种用js指定的事件处理程序的形参当然可以随便命名了,一般简写为e
了。
DOM0
仍然用上面的声明函数:
function clickHandler(e) {
console.log(e.target);
}
document.getElementsByTagName('button')[0].onclick = clickHandler;
准确的打印出了button元素。
其实还可以将事件处理函数定义为无参函数,可以用arguments来获取事件对象。
function clickHandler1() { //无参处理函数
var e = arguments[0];
console.log(e.target);
}
DOM2
最常用的就是dom2级事件处理程序了:
document.getElementsByTagName('button')[0].addEventListener('click', clickHandler, false );
同样也可以使用无参函数
document.getElementsByTagName('button')[0].addEventListener('click', clickHandler1, false );
匿名函数时候需要注意的
DOM1和2级事件处理程序也常用匿名函数的方式:
document.getElementsByTagName('button')[0].onclick = (e) => {
console.log(e.target);
}
这样传入event
参数的有参匿名函数是没有问题的,但是如果用无参函数的话下面代码就会报错出问题:
document.getElementsByTagName('button')[0].onclick = () => {
var e = arguments[0];
console.log(e.target);
}
根据MDN上描述,arguments不能使用箭头函数,因为箭头函数没有自己的this,使用的是封闭执行作用域的this。
但是若非要使用arguments的话可以传入...args:
document.getElementsByTagName('button')[0].onclick = (...args) => {
var e = args[0];
console.log(e.target);
}
事件处理程序传递多个参数
在最早的HTML事件处理程序中我们可以直接传入多个参数,
<button onclick="clickHandler(event, 'a', 'b')">屠龙宝刀点击就送</button>
但是DOM0和2级事件处理程序默认只传入event
参数,可以采用闭包的方法(IIFE)来处理:
document.getElementsByTagName('button')[0].addEventListener('click', (function(a, b) {
return function(e) {clickHandler(e, a, b); };
}) ('a', 'b'), false);
event.target
和event.currentTarget
既然都写了事件处理程序顺便再复习下这两个的区别,target
是事件的实际目标,currentTarget
是处理事件的元素,也就是绑定事件函数的元素,事件处理函数中this
的值等于currentTarget
。
在线演示
参考资料
- js高级程序设计(第三版)
- Javascript event handler with parameters
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。