首页 > 网站 > WEB开发 > 正文

JavaScript--事件绑定及深入(26)

2024-04-27 14:11:06
字体:
来源:转载
供稿:网友

javaScript--事件绑定及深入(26)

// 事件绑定分为两种:

// 一种是传统事件绑定(内联模型/脚本模型);上一章内容;

// 一种是现代事件绑定(DOM2级模型);现代事件绑定在传统事件绑定基础上提供了更强大的功能;

一 传统事件绑定的问题

 1 // 脚本模型将一个函数赋值给一个事件处理函数; 2     var box = document.getElementById('box');    // 获取元素; 3     box.onclick = function(){                    // 元素点击触发事件; 4         alert('Lee'); 5     } 6  7 // 问题一:一个事件处理函数触发两次事件; 8     window.onload = function(){                  // 第一组程序; 9         alert('Lee');10     }11     window.onload = function(){                  // 第二组程序;12         alert('Mr.Lee');13     }14     // PS:当两组程序同时执行的时候,后面一个会把前面一个完全覆盖;15     // 导致前面的window.onload完全失效了;16 // 解决方案:17     window.onload = function(){                  // 第一组事件处理程序,会被覆盖;18         alert('Lee');19     }20     if(typeof window.onload == 'function'){      // 判断之前是否有window.onload;21         var saved = null;                        // 创建一个保存器;22         saved = window.onload;                   // 把之前的window.onload保存起来;23     }24     window.onload = function(){                  // 下一个要执行的事件;25         // saved()=window.onload = function26         if(saved)saved();                        // 判断之前是否有事件,如果有则先执行之前保存的事件;27         alert('Mr.Lee');                         // 执行本事件的代码;28     }
// 问题二:事件切换器    box.onclick = boBlue;                         // 第一次执行toBlue();    function toRed(){        this.className = 'red';        this.onclick = toBlue;                    // 第三次执行roBlue(),然后来回切换;    }    function toBlue(){        this.className = 'blue';        this.onclick = toRed;                    // 第二次执行toRed();    }    // 这个切换器在扩展的时候,会出现一些问题:    1.如果增加一个执行函数,那么会被覆盖;    box.onclick = toAlert;                       // 被增加的函数;    box.onclick = toBlue;                        // toAlert被覆盖了;    2.如果解决覆盖问题,就必须包含同时执行;    box.onclick = function(){                    // 包含进去,但可读性降低;        toAlert();                               // 第一次不会被覆盖,但第二次又被覆盖;        toBlue.call(this);                       // 还必须把this传递到切换器里;    }
 1 // 综上三个问题:覆盖问题/可读性问题/this传递为题; 2 // 我们创建一个自定义事件处理函数; 3     function addEvent(obj,type,fn){             // 取代传统事件处理函数; 4         var saved = null;                       // 保存每次触发的事件处理函数; 5         if(typeof obj['on'+type] == 'function'){// 判断是不是存在事件; 6             saved = obj['on'+type];             // 如果有,保存起来; 7         } 8         obj['on'+type] = function(){            // 然后执行; 9             if(saved)saved();                   // 执行上一个;10             fn.call(this);                      // 执行函数,把this传递进去;11         }12     }13     addEvent(window,'load',function(){14         alert('Lee');                           // 可以执行;15     });16     addEvent(window.'load',function(){17         alert('Mr.Lee');                        // 可以执行;18     })19 20 // 用自定义事件函数注册到切换器上查看效果:21     addEvent(window,'load',function(){22         var box = document.getElementById('box');23         addEvent(box,'click',toBlue);24     });25     function toRed(){26         this.className = 'red';27         addEvent(this,'click',toBlue);28     }29     function toBlue(){30         this.className = 'blue';31         addEvent(this,'click',toRed);32     

二 W3C事件处理函数

// "DOM2级事件"定义了两个方法,用于添加事件删除事件的处理程序:addEventListener()和removeEventListener();

 1 // 所有DOM节点中都包含这两个方法,并且它们都接收3个参数:事件名/函数/冒泡或捕获的布尔值(true表示捕获,false表示冒泡); 2     window.addEventListener('load',function(){ 3         alert('Lee'); 4     },false); 5     window.addEventListener('load',function(){ 6         alert('Mr.Lee'); 7     },false); 8     // PS:W3C的事件绑定好处:1.不需要自定义了;2.可以屏蔽相同的函数;3.可以设置冒泡和捕获; 9     window.addEventListener('load',init,false);        // 第一次执行了;10     window.addEventListener('load',init,false);        // 第二次被屏蔽了;11     function init(){12         alert('Lee');13     }14 15 // 事件切换器16     window.addEventListener('load',function(){17         var box = document.getElementById('box');18         box.addEventListener('click',function(){       // 不会被覆盖/误删;19             alert('Lee');20         },false);21         box.addEventListener('click',toBlue,false);    // 引入切换;22     },false);23 24     function toRed(){25         this.className = 'red';26         this.removeEventListener('click',toRed,false); // 移除事件处理函数;27         this.addEventListener('click',toBlue,false);   // 添加需要切换的事件处理函数; 28     }29 30     function toBlue(){31         this.className = 'blue';32         this.removeEventListener('click',toBlue,false);33         this.addEventListener('click',toRed,false);34     }35 36 // 设置冒泡和捕获阶段37     document.addEventListener('click',function(){38         alert('document');39     },true);                                        // 设置为捕获;40 41     document.addEventListener('click',function(){42         alert('Lee');43     },false);                                        // 设置为冒泡;

三 IE事件处理函数

// IE中实现了与DOM中类似的两个方法:attachEvent()和detachEvent();

// 这两个方法接收相同的参数:事件名函数;

 1 // 在使用这两组函数的时候,区别: 2 // 1.IE不支持捕获,只支持冒泡; 3 // 2.IE添加事件不能屏蔽重复的函数; 4 // 3.IE中的this指向的是window而不是DOM对象; 5 // 4.在传统事件上,IE是无法接受到event对象的;但使用了attachEvent()却可以; 6     window.attachEvent('onload',function(){ 7         var box = document.getElementById('box'); 8         box.attachEvent('onclick',toBlue); 9     });10 11     function toRed(){12         var that = window.event.srcElement;13         that.className = 'red';14         that.detachEvent('onclick',toRed);15         that.attachEvent('onclick',toBlue);16     }17 18     function toBlue(){19         var that = window.event.srcElement;20         that.className = 'blue';21         that.detachEvent('onclick',toBlue);22         that.attachEvent('onclick',toRed);23     }24     // PS:IE不支持捕获;25     // IE不能屏蔽;26     // IE不能传递this,可以call过去;27 28 // 在传统绑定上,IE是无法像W3C那样通过传参接受event对象;但如果使用了attachEvent()却可以;29     box.onclick = function(evt){30         alert(evt);                                // undefined;31     }32 33     box.attachEvent('onclick',function(evt){34         alert(evt);                                // object;35         alert(evt.type);                           // click;36     });37 38 // 兼容IE和W3C的事件切换器函数;39     function addEvent(obj,type,fn){                // 添加事件处理程序兼容;40         if(obj.addEventListener){41             obj.addEventListener(type,fn);42         }else if(obj.attachEvent){43             obj.attachEvent('on'+type,fn);44         }45     }46 47     function removeEvent(obj,type,fn){            // 移除事件处理程序兼容;48         if(obj.removeEventListener){49             obj.removeEventListener(type,fn);50         }esle if(obj.detachEvent){51             obj.detachEvent('on'+type,fn);52         }53     }54 55     function getTarget(evt){                     // 得到事件目标;56         if(evt.target){57             return evt.target;58         }else if(window.event.srcEleemnt){59             return window.event.srcElement;60         }61     }

四 事件对象补充

 1 1.relatedTarget 2 // 这个属性可以在mouSEOver和mouseout事件中获取从哪里移入从哪里移出的DOM对象; 3     box.onmouseover = function(evt){            // 鼠标移入box; 4         alert(evt.relatedTarget);               // 获取移入box之前的那个元素; 5     } 6     box.onmouseout = function(evt){             // 鼠标移出box; 7         alert(evt.relatedTarget);               // 获取移出box之后到的那个元素; 8     } 9 10 // IE提供了两组与之对应的属性:fromElement和toElement;11 // 兼容函数12     function getEarget(evt){13         var e = evt || window.event;            // 得到事件对象;14         if(e.srcElement){                       // 如果支持srcElement,表示IE;15             if(e.type == 'mouseover'){          // 如果是over事件;16                 return e.fromeElement;          // 就使用from;17             }else if(e.type == 'mouseout'){     // 如果是out;
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表