如何触发一个事件
元素.on事件类型=function(){};
句柄绑定
程序 this 指向的是元素本身(函数内部的 this )
一个对象的一个事件,只能绑定一个处理函数
(下面这个例子:点击小方块 控制台上只会显示 b)
<div style="background-color: red;width: 50px;height: 50px;"></div>
<script type="text/javascript">
var div=document.getElementsByTagName("div")[0];
var y=1;
if(y==1){
div.onclick=function(){
console.log("a");
}
y=2;
}
if(y==2){
div.onclick=function(){
console.log("b");
}
}
</script>
- 基本等同于写在HTML行间上
(写法1 和 写法2两者的效果一样)
//写法1
<div style="background-color: red;width: 50px;height: 50px;" onclick="console.log('a')"></div>
//写法2
<div style="background-color: red;width: 50px;height: 50px;"></div>
<script type="text/javascript">
var div=document.getElementsByTagName("div")[0];
div.onclick=function(){
console.log("a");
}
</script>
- 推荐使用(下面两种方法):
元素.addEventListener('事件类型',处理函数,false);
div.addEventListener('click',function(){
//函数引用 类似于text (函数名)
},false);
- 可以给一个对象绑定多个事件(绑定多个处理函数) (按绑定的顺序去执行)
(点击小方块 在控制台的运行结果:一次性打印下出a b(a在b前面)) - 程序 this 指向的是元素本身
<div style="background-color: red;width: 50px;height: 50px;"></div>
<script type="text/javascript">
var div=document.getElementsByTagName("div")[0];
var y=1;
if(y==1){
div.addEventListener('click',function(){
console.log("a");
},false)
y=2;
}
if(y==2){
div.addEventListener('click',function(){
console.log("b");
},false)
}
来我们来看一个有意思的东西:
//例1
<div style="background-color: red;width: 50px;height: 50px;"></div>
<script type="text/javascript">
var div=document.getElementsByTagName("div")[0];
var y=1;
div.addEventListener('click',function(){
console.log("a");
},false)
div.addEventListener('click',function(){
console.log("a"); //点击小方块在控制台上一次出现两个a
},false)
</script>
我们来换一种写法:
//例2
<div style="background-color: red;width: 50px;height: 50px;"></div>
<script type="text/javascript">
var div=document.getElementsByTagName("div")[0];
var y=1;
div.addEventListener('click',text,false)
div.addEventListener('click',text,false)
function text(){
console.log("a"); //点击小方块在控制台上一次出现一个a
}
</script>
这是为什么呢?
这里我们说的绑定多个事件 指的是绑定多个处理函数,很明显例2 的处理函数是一个 所以就相当于绑定一个事件了(同一个函数绑定多次 只能执行一次)
元素.attachEvent('on事件类型',处理函数)
IE独有
div.attachEvent('onclick',function(){
})
- 基本用法和 addEventListener一样(不同处:同一个函数可以绑定多次)
- 程序 this 指向 window
(那么问题来了 有时候我们点击事件中并不确定是哪个元素 这个时候我们就需要用 this 替代这个未知的元素,可这里的this 指的是全局 那要如何达到我们想要的结果呢 ? )
div.attachEvent('onclick',function(){
text.call(div);
});
function text(){
//此时这里的 this = div
}
事件绑定上的闭包问题
- 整体事件绑定可以用for循环
那我们来看一个小例子:(我们如果想要实现 点击四个列表小圆点 控制台上可以显示出他们的对应点击顺序)
//HTML代码
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
或许你的js代码这样写:
//错误方法 !!
<script type="text/javascript">
var li=document.getElementsByTagName("li");
//给每个li加上事件
for(var i=0;i<li.length;i++){
li[i].addEventListener('click',function(){
console.log(i);
},false);
}
</script>
(可这是错误的 不论点击那个小圆点 控制台上都只会显示4)
这是为什么呢?还记得我们之前讨论过的闭包吗。就是因为产生了闭包 使得function函数中保存的 i 值一直都为 4。
//改写的解决方法
<script type="text/javascript">
var li=document.getElementsByTagName("li");
//给每个li加上事件
for(var i=0;i<li.length;i++){
(function(i){ //我们用立即执行函数解决这个问题
li[i].addEventListener('click',function(){
console.log(i+1);
},false);
}(i))
} //此时点击对应的小圆点,依次在控制台显示对应的序列(1~4)
</script>
! ! ! 绑定事件,一旦事件出现在循环里面就要考虑闭包
当然我们可以换一种写法:(给每个 li 自定义一个属性)
<body>
<ul>
<li name="1"></li> <!--name为自定义属性名-->
<li name="2"></li>
<li name="3"></li>
<li name="4"></li>
</ul>
<script type="text/javascript">
var li=document.getElementsByTagName("li");
for(var i=0;i<li.length;i++){
li[i].addEventListener('click',function(){
console.log(parseInt(this.getAttribute("name")));
},false) //获取自定义属性名
}
</script>
</body>
(适用于各类浏览器 封装好的事件处理函数:)
事件解除
div.onclick=null;
直接让它为空
比如说我们想实现 只能实现一次的事件:
<script type="text/javascript">
div=document.getElementsByTagName("div")[0];
div.onclick=function(){
console.log('a');
this.onclick=null;
}
</script>
<script type="text/javascript"> //实现点击5次的
div=document.getElementsByTagName("div")[0];
var i=0;
div.onclick=function(){
i++;
console.log('a');
if(i==5){
this.onclick=null;}
}
div.onclick=null;
</script>
- 后面两个 若绑定匿名函数,则无法解除
元素.removeEventListener('事件类型',处理函数,false);
<script type="text/javascript">
var div=document.getElementsByTagName("div")[0];
div.addEventListener('click',text,false); //如果要解除事件 不能用匿名函数
div.removeEventListener('click',text,false);
function text(){
console.log("a");
}
</script>
元素.detachEvent('on事件类型',处理函数);