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等事件不冒泡。