事件委托

来源:互联网 发布:软件编写入门视频 编辑:程序博客网 时间:2024/06/16 18:17

事件委托

<!DOCTYPE html><html lang="en"><head>    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >    <title></title></head><body>    <ul id="myLinks">        <li id="goSomewhere">Go somewhere</li>        <li id="doSomething">Do something</li>        <li id="sayHi">Say hi</li>    </ul>    <script type="text/javascript">    window.onload= function() {        var list = document.getElementById("myLinks");        addHandler(list, "click", function(ev) {            var oEvent = ev||event;            var target = getTarget(oEvent);            switch(target.id) {                case "doSomething":                    document.title = "I changed the document's title";                    break;                case "goSomewhere":                    location.href = "http://www.baidu.com";                    break;                case "sayHi":                    alert("hi");                    break;            }        })    }    function getTarget(event)    {        return event.target || event.srcElement;    }    function addHandler(element, type, handler)    {        if(element.addEventListener)        {            element.addEventListener(type, handler, false);//IE9、ff、sa、op、ch        }else if (element.attachEvent)        {            element.attachEvent("on" + type, handler);//IE、op        }else        {            element["on" + type] = handle;        }    }    </script></body></html>

委托(代理)事件是那些被绑定到父级元素的事件,但是只有当满足一定匹配条件时才会被挪。这是靠事件的冒泡机制来实现的,

优点是:

(1)可以大量节省内存占用,减少事件注册,比如在table上代理所有td的click事件就非常棒

(2)可以实现当新增子对象时无需再次对其绑定事件,对于动态内容部分尤为合适

缺点是:

事件代理的应用常用应该仅限于上述需求下,如果把所有事件都用代理就可能会出现事件误判,即本不应用触发事件的被绑上了事件。


实现事件模型bind与trigger

大致实现思路就是创建一个类或是匿名函数,在bind和trigger函数外层作用域创建一个字典对象,用于存储注册的事件及响应函数列表,bind时,如果字典没有则创建一个,key是事件名称,value是数组,里面放着当前注册的响应函数,如果字段中有,那么就直接push到数组即可。trigger时调出来依次触发事件响应函数即可。
  

function Emitter() {    this._listener = [];    //_listener[自定义的事件名] = [所用执行的匿名函数1, 所用执行的匿名函数2]}//注册事件Emitter.prototype.bind = function(eventName, callback) {    //this._listener[eventName]没有值则将listener定义为[](数组)。    listener.push(callback);    this._listener[eventName] = listener;} //触发事件Emitter.prototype.trigger = function(eventName) {    var args = Array.prototype.slice.apply(arguments).slice(1);    //atgs为获得除了eventName后面的参数(注册事件的参数)    var listener = this._listener[eventName];    if(!Array.isArray(listener)) return;//自定义事件名不存在    listener.forEach(function(callback) {        try {            callback.apply(this, args);        }catch(e) {            console.error(e);        }    })}//实例var emitter = new Emitter();    emitter.bind("myevent", function(arg1, arg2) {        console.log(arg1, arg2);    });    emitter.bind("myevent", function(arg1, arg2) {        console.log(arg2, arg1);    });    emitter.trigger('myevent', "a", "b");


事件广播(dispatchEvent)

一般我们在元素上绑定事件后,是靠用户在这些元素上的鼠标行为来捕获或者触发事件的,或者自带的浏览器行为事件,比如click,mouseover,load等等,有些时候我们需要自定义事件或者在特定的情况下需要触发这些事件。这个时候我们可以使用IE下fireEvent方法,高级浏览器(chrome,firefox等)有dispatchEvent方法。

ie下的例子:

//document上绑定自定义事件ondataavailabledocument.attachEvent('ondataavailable', function (event) {    alert(event.eventType);});var obj=document.getElementById("obj");//obj元素上绑定click事件obj.attachEvent('onclick', function (event) {alert(event.eventType);});//调用document对象的createEventObject方法得到一个event的对象实例。var event = document.createEventObject();event.eventType = 'message';//触发document上绑定的自定义事件ondataavailabledocument.fireEvent('ondataavailable', event);//触发obj元素上绑定click事件document.getElementById("test").onclick = function () {    obj.fireEvent('onclick', event);};

高级浏览器(chrome,firefox等)的例子:

//document上绑定自定义事件ondataavailabledocument.addEventListener('ondataavailable', function (event) {    alert(event.eventType);}, false);var obj = document.getElementById("obj");//obj元素上绑定click事件obj.addEventListener('click', function (event) {    alert(event.eventType);}, false);//调用document对象的 createEvent 方法得到一个event的对象实例。var event = document.createEvent('HTMLEvents');// initEvent接受3个参数:// 事件类型,是否冒泡,是否阻止浏览器的默认行为event.initEvent("ondataavailable", true, true);event.eventType = 'message';//触发document上绑定的自定义事件ondataavailabledocument.dispatchEvent(event);var event1 = document.createEvent('HTMLEvents');event1.initEvent("click", true, true);event1.eventType = 'message';//触发obj元素上绑定click事件document.getElementById("test").onclick = function () {    obj.dispatchEvent(event1);};
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 电脑优酷下载总显示未知错误怎么办 文本文档打开时显字符丢失怎么办 系统文件过大无法放进u盘怎么办 淘宝上买的密钥激活不了怎么办 苹果手机玩游戏屏幕卡住不动怎么办 电脑系统安装好一排英文字怎么办 赴日签证申请表写错了怎么办 不知道自己想要做什么工作怎么办 三星note4微信出现闪退怎么办 魅蓝note6手机自动闪退怎么办 苹果6s系统内存占用量过大怎么办 想在一年通过会计初级和中级怎么办 特殊岗位退休档察写的力工怎么办 面试时期望工资说低了。怎么办 面试时期望薪资写低了怎么办 高考后比一模差了80分怎么办 戒了烟我不习惯没有你我怎么办 没有你我不习惯没有你我怎么办 做什么都没兴趣嫌麻烦怎么办 快递还在路上就确认收货了怎么办 微信显示时间与手机不符怎么办 微信提示银行卡预留手机不符怎么办 得了湿疹后吃了海鲜严重了怎么办 看到小区街道乱扔的垃圾你会怎么办 去韩国干服务员不会讲韩语怎么办 华为手机键盘变英文字母大了怎么办 淘宝申请售后卖家余额不足怎么办 发票名称少写了一个字怎么办 微博数量与实际数量不一致怎么办 在淘宝中要买的商品卖完了怎么办 病因写错了保险不报销怎么办? 上学期间保险名字写错了怎么办 塑料盆上的商标纸撕了胶怎么办 川航买机票名字错了两个字怎么办 买机票护照号码填错了怎么办 换旅行证给孩子改名字怎么办 浦发信用卡卡片名字印错了怎么办 公主工作很辛苦坚持不下去怎么办 在表格里怎么办名字转换成拼音 激素脸有黑头毛孔大该怎么办 兢兢业业上班但不招领导喜欢怎么办