HTML事件绑定
可以直接通过 html 事件属性来绑定 js 执行代码,属性由 "on" 后面跟着事件名组成。onclick、onchange、onload、onmouseover等。注意这些属性名是区分大小写的,所有都是小写,即使事件类型是由多个词组成。
定义的事件处理程序可以包含要执行的具体动作,也可以调用在页面其他地方定义的脚本。这段代码应该是事件处理程序函数的主体,而非完整的函数声明。也就是说,这段代码不应该用大括号包围且使用function关键字作为前缀。
<button onclick="console.log(this)">click</button>
// 这里的 this 是button元素
--------
<button onclick="say()">click</button>
function say() {
console.log(this)
}
// 这里的 this 是window
// html 事件绑定的函数在执行时,有权访问全局作用域中的任何代码。也即我们可以在 html 中可以直接调用 script 标签中定义的函数。
--------
<button onclick="obj.say()">click</button>
let obj = {
say: function() {
console.log(this)
}
}
// 这里的 this 是obj
总结:当绑定的函数是一个直接执行的语句(第一种),并且显示的传入一个this时,此时 this 指向该调用元素,如果是其他情况,根据 this 的定义确定即可。
缺点:
- 不利于表现层和逻辑层代码分离
- 用户可能会在HTML元素一出现在页面上就触发相应的事件,但当时的事件处理程序有可能尚不具备执行条件。以前面的例子来说明,假设 showMessage() 函数是在按钮下方、页面的最底部定义的。如果用户在页面解析 showMessage() 函数之前就单击了按钮,就会引发错误。
DOM元素事件绑定
给 DOM 元素绑定事件相当于是从 attribute 改成了 property,浏览器的兼容性异常优异,方法就是将这种属性的值设置为一个函数。
<button id="btn">click</button>
let oBtn = document.getElementById('btn');
oBtn.onclick = say; // 这里的 this 是button元素
function say() {
console.log(this)
}
--------
let obj = {
say: function() {
console.log(this)
}
}
oBtn.onclick = obj.say;
// 这里的 this 也是button元素
oBtn.onclick = null;
// 删除事件处理程序
// html 上绑定的事件也可以通过这种方式来解绑
总结:绑定的事件处理程序被附值给了元素的方法,也即 this 指向该目标元素。
缺点:一个元素只能绑定一个处理函数
addEventListener 绑定函数
这里不说使用方法了,很简单
<button id="btn">click</button>
let oBtn = document.getElementById('btn');
oBtn.addEventListener('click', function(){
console.log(this) // 这里的 this 是button元素
}, false)
--------
oBtn.addEventListener('click', say, false)
function say() {
console.log(this) // 这里的 this 也是button元素
}
--------
let obj = {
say: function() {
console.log(this)
}
}
oBtn.addEventListener('click', obj.say, false)
// 这里的 this 也是button元素
总结:addEventListener 参数中回调函数的this指向目标元素。
常用的解决办法:
oBtn.addEventListener('click', obj.say.bind(obj), false);
// 通过使用bind,为回调函数绑定指定的 this