JavaScript之事件篇
1.交互和事件的定义:
交互就是你对程序作了一个小动作,程序给你的一个反馈。事件就是交互体验的核心功能。事件就是一个动作,没效果也是事件,比如说一个 div, 你点击一下他没有效果,但是也可以被点击,他天生就有被点击的事件。
2.如何绑定事件处理函数:
我们说一个元素天生就有事件,天生就可以被别人操作,我们绑定的只是事件处理函数,就是当你点击之后给你的反馈。
(1)dom.onxxx = function (){}
比如说:
<div style="width: 100px;height: 100px;background-color: red;"></div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
div.onclick = function () {
this.style.backgroundColor = 'green';
}
</script>
这样就是通过 on 的方式给这个 div 绑定一个 click 事件,即点击事件,那么当你点击的时候他的背景颜色就变绿了。这个绑定方式兼容性非常好,但是一个元素的同一个事件上只能绑定一个处理函数,比如说:
div.onclick = function () {
console.log("a");
}
div.onclick = function () {
console.log("b");
}
这样是不可以的,因为虽然他是事件,但是他也属于给对象上的属性赋值,你这么写的话后边的就会覆盖掉前边的。然后这种绑定方式基本等同于写在 HTML 行间上,就是比如说:
<div style="width:100px;height:100px;background-color:red;" onclick="console.log('a')"></div>
我们可以把它直接写在行间,效果是一样的,行间就不用写 function 了,这种叫做句柄的写法,dom.onxxx = function ( ){ }叫做句柄的绑定方式。
(2)dom.addEventListener()
这是最标准的绑定方法,里边需要传三个参数,第一个是事件类型,第二个是处理函数,第三个传 false。比如上边那个 div:
div.addEventListener('click',function (){
console.log('a');
},false)
这样也可以实现 click 事件的绑定,然后这个可以为一个事件绑定多个处理程序,比如说:
div.addEventListener('click',function (){
console.log('a');
},false)
div.addEventListener('click',function (){
console.log('a');
},false)
这样就能点一次打印两个 a,但是比如说:
div.addEventListener('click',test,false)
div.addEventListener('click',test,false)
function test(){
console.log('a');
}
这样点击一次只能打印一个 a,因为上边的绑定的函数虽然长得一样,但是是两个人,下边显然是一个人,所以说这个方法同一个函数不能重复绑定多次,还有就是 ie9 以下不兼容。
(3)dom.attachEvent() (ie 独有)
这个方法是 ie 独有的,里边传入两个参数,第一个是“on” + 事件类型,第二个是处理函数,比如说:
div.attachEvent('onclick',function(){
console.log('a');
})
这个方法和 dom.addEventListener()极其类似,也可以为一个事件绑定多个处理程序,而且同一个函数可以重复绑定多次。
3.事件处理程序的运行环境:
(1)dom.onxxx = function () {} 程序 this 指向 dom 元素本身,比如说:
<div style="width: 100px;height: 100px;background-color: red;"></div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
div.onclick = function () {
console.log(this)
}
</script>
你点击这个 div 后控制台就会打印:
(2)dom.addEventListener() 程序 this 指向 dom 元素本身,还是上边的 div:
div.addEventListener('click',function(){
console.log(this);
},false)
点击 div 控制台打印
(3)dom.attachEvent()
程序 this 指向 window,这是一个 bug。那我现在就想让 this 指向调用者,可以这么写,比如还是上边的 div:
div.attachEvent('onclick',function(){
handle.call(div);
})
function handle(){
console.log(this)
}
我把事件处理的程序写在外边,然后事件的第二个参数函数里执行外部的函数并用 call 把 div 传进去,那么外部的函数里就可以用 this 了,他就通过 call 的方式让 this 指向 div 了。
练习:
封装兼容性方法 addEvent(),给一个 dom 对象添加一个事件处理函数。
function addEvent(elem,type,handle){
if(elem.addEventListener){
elem.addEventListener(type,handle,false);
}else if(elem.attachEvent){
elem.attachEvent('on' + type, function(){
handle.call(elem);
});
}else{
elem['on' + type] = handle;
}
}
解析:我们封装的方法里边传三个参数,第一个是 dom 元素,第二个是事件类型,第三个是处理函数,然后里边就比较简单了,就是第二个 else if 里要把 this 指向处理好,然后最后如果两个方法都不好使,就用 dom.onxxx = function () {}这种,因为传进去是字符串形式的,所以必须加中括号。
4.解除事件处理程序
(1)dom.onxxx = null
比如说一个 div 绑定的这个处理函数只能让他点击第一次的时候起作用,以后就不起作用了,就可以让他执行完后 onclick 属性就等于 null
<div style="width: 100px;height: 100px;background-color: red;"></div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
div.onclick = function () {
console.log('a');
this.onclick = null;
}
</script>
(2)dom.removeEventListener()
这个和 addEventListener 是对应的,里边传入三个参数,第一个是事件类型,第二个是处理函数,第三个是 false,而且要和 addEventListener 的 dom 元素相对应,事件类型相对应,最重要的是处理函数得是一个人,所以你只能把函数提取出来,然后传参的时候放引用:
<div style="width: 100px;height: 100px;background-color: red;"></div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0];
div.addEventListener('click',handle,false);
div.removeEventListener('click',handle,false);
function handle(){
console.log('a');
}
</script>
(3)dom.detachEvent() (ie 独有)
这个和 attachEvent()对应,里边传入两个参数,第一个是“on”+ 事件类型,第二个 是处理函数,也是必须一一对应,然后处理函数得是一个人。