AI智能
改变未来

js事件绑定解除、事件处理模型


 

1、事件重要吗?

重要!是交互体验的核心功能

2、如何绑定事件处理函数?

[code]  <style>#myDiv{width: 200px;height: 100px;background-color: pink;}</style><div id=\"myDiv\"></div>var myDiv=document.getElementById(\"myDiv\");
  • ele.onxxx = function (event) {} ;  兼容性很好,但是一个元素只能绑定一个处理函数,基本等同于写在HTML行间上

执行环境:程序this指向是dom元素本身

[code]      myDiv.onclick=function(){myDiv.style.backgroundColor=\"green\";}
  • ele.addEventListener(type, fn, false);  (最正式的绑定方法)IE9以下不兼容(W3C标准),可以为一个事件绑定多个处理函数,其中type是事件处理类型,前面不用加“on”,fn是处理函数

执行环境:程序this指向是dom元素本身

[code]  myDiv.addEventListener(\"click\",function(){myDiv.style.backgroundColor=\"green\";//此处匿名函数是函数引用},false)
  • ele.attachEvent(‘on’ + type, fn);  IE独有,一个事件同样可以绑定多个处理程序 

执行环境:程序this指向window

[code] myDiv.attachEvent(\"onclick\",function(){myDiv.style.backgroundColor=\"green\";})

练习一:

使用原生js,addEventListener为每个li元素绑定一个click事件输出他们的顺序,(考察点:事件、闭包、立即执行函数)

[code]    <ul><li>a</li><li>b</li><li>c</li><li>d</li></ul><script>//错误方法var list=document.getElementsByTagName(\"li\");for(var i=0;i<list.length;i++){list[i].addEventListener(\"click\",function(){  //形成闭包,函数写在循环里要考虑是否出现闭包,改为立即执行函数console.log(i);//只输出结果4},false);}//改为:for(var i=0;i<list.length;i++){(function(i){list[i].addEventListener(\"click\",function(){  //闭包,函数写在循环里要考虑是否出现闭包,改为立即执行函数console.log(i);//正确输出次序},false);}(i))}

练习二:封装一个事件处理函数

this指向window,如何改变this指向为div?

解决:

 此时this指向myDiv 

结果:

[code]  <div id=\"myDiv\"></div><script>//处理针对不同浏览器兼容性,给一个dom对象添加该事件类型的处理函数(3个参数)var myDiv=document.getElementById(\"myDiv\");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;}}

3、解除事件绑定?

  • ele.onclick = false/‘’/null;
  • ele.removeEventListener(type, fn, false);
  • ele.detachEvent(‘on’ + type, fn);
  • 注:若绑定匿名函数,则无法解除
[code] myDiv.onclick=function(){myDiv.style.backgroundColor=\"green\";}myDiv.onclick = null;//解除事件
[code]  <style>#myDiv{width: 200px;height: 100px;background-color: pink;}</style><div id=\"myDiv\"></div><script>var myDiv=document.getElementById(\"myDiv\");myDiv.addEventListener(\"click\",test,false);//绑定事件函数function test(){myDiv.style.backgroundColor=\"green\";}myDiv.removeEventListener(\"click\",test,false);//解除绑定</script>

4、事件处理模型(冒泡、捕获)

一个对象的一个事件类型只能遵循一种事件处理模型(要么冒泡,要么捕获)

(1)事件冒泡

结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一事件,会从结构上的子元素冒泡向父元素。(自底向上)

例如下面代码:点击粉色区域时,也会触发蓝色和红色的事件 。因为这三个颜色块在结构上存在嵌套关系,如果事件点击到到子元素上,子元素会一层一层向父元素传递这个事件。注意输出的顺序:pink-blue-red;由子元素向父元素

代码: 

[code] <style>#wrapper{width: 200px;height: 200px;background-color: red;}#content{width: 150px;height: 150px;background-color: blue;}#box{width: 100px;height: 100px;background-color: pink;}</style></head><body><div id=\"wrapper\"><div id=\"content\"><div id=\"box\"></div></div></div><script>var wrapper=document.getElementById(\"wrapper\");var content=document.getElementById(\"content\");var box=document.getElementById(\"box\");wrapper.addEventListener(\"click\",function(){console.log(\"red\");},false);content.addEventListener(\"click\",function(){console.log(\"blue\");},false);box.addEventListener(\"click\",function(){console.log(\"pink\");},false);

(2)事件捕获(IE不支持捕获时间)

当ele.addEventListener(type, fn, false);中的false变为true就能实现事件捕获。

结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)。(自底向上)

例如上面例子将false改为true之后

点击粉色区域时,也会触发蓝色和红色的事件 。但是这里的顺序是red-blue-pink,由父元素向子元素。

(3)哪个先执行呢?

触发顺序,先捕获,后冒泡

例如:一个对象的一个事件类型上面绑定两个处理函数,分别遵循事件冒泡和事件捕获。

结果解释,点击pink区域,执行结果是先捕获,后冒泡。中间的两个输出结果是,pink的两次事件执行。

focus、blur、change、submit、reset、select等事件不冒泡。 

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » js事件绑定解除、事件处理模型