web前端|js教程
javascript,事件,js
web前端-js教程
javascript中使用addEventListener()或attachEvent()绑定事件时会有几个小问题:
php广告任务源码,vscode源码内部结构,ubuntu 改字体,tomcat正常运行错误,网页爬虫+交通,php 静态构造函数,学seo需要多久霸屏,医院手机网站模板,登录框模板lzw
A、使用addEventListener()或attachEvent()添加的匿名函数无法移除。
网站机器人php源码,ubuntu账户锁定设置,tomcat日志管理工具,海边 爬虫 学名,php在圆里面画方块,seo技术灵lzw
var oBtn = document.getElementById(tn);oBtn.addEventListener(click,function(){ alert(utton is clicked)},false)oBtn.reomveEventListener(click,function(){ alert(utton is clicked)},false)//oBtn上的事件无法移除,因为传入的是一个匿名函数
B、ie6-ie8中,使用attachEvent()绑定多个事件的倒序执行问题。
xss.me平台源码,vscode教程vuejs,ubuntu更新驱动后卡在,tomcat实时查询,sqlite c++类,jquery 时间选择插件,omi前端框架如何看待,财联社爬虫登录,网页php代码,joomla seo,外贸公司企业网站源码,网页制作素材网站html,数码商城源码模板,html简单页面代码,智慧物业管理系统源码免费分享,php家教程序lzw
var oBtn = document.getElementById(tn);oBtn.attachEvent(onclick,function(){ alert(1)})oBtn.attachEvent(onclick,function(){ alert(2)})oBtn.attachEvent(onclick,function(){ alert(3)})//ie9+ 下执行顺序1、2、3//ie6-ie8下执行顺序3、2、1
解决问题
想写一个跨浏览器的事件绑定模块,这样以后可以复用,同时我想解决上诉问题。JQuery内部使用事件队列和数据缓存机制解决此问题,看了下相关源码,实在复杂,自个试了一些方法,勉强实现。贴段代码,原来是用面向对象写的,不想让人看得很复杂,所有改成函数来组织。
/*绑定事件的接口 * *@param {dom-DOM}和{type-string}和{fn-function} 可选参数{fnName-string} *@execute 创建事件队列,添加到DOM对象属性上, 将事件处理程序(函数)加入事件队列 可为事件处理程序添加一个标识符,用于删除指定事件处理程序 */ function bind(dom,type,fn,fnName){ dom.eventQueue = dom.eventQueue || {}; dom.eventQueue[type] = dom.eventQueue[type] || {}; dom.handler = dom.handler || {}; if (!fnName) { var index = queueLength(dom,type); dom.eventQueue[type][fnQueue+index] = fn; } else { dom.eventQueue[type][fnName] = fn; }; if (!dom.handler[type]) bindEvent(dom,type);};/*绑定事件 * *@param {dom-DOM}和{type-string} *@execute 只绑定一次事件,handler用于遍历执行事件队列中的事件处理程序(函数) *@caller bind() */function bindEvent(dom,type){ dom.handler[type] = function(){ for(var guid in dom.eventQueue[type]){ dom.eventQueue[type][guid].call(dom); } }; if (window.addEventListener) { dom.addEventListener(type,dom.handler[type],false); } else { dom.attachEvent(on+type,dom.handler[type]); };};/*移除事件的接口 * *@param {dom-DOM}和{type-string} 可选参数{fnName-function} *@execute 如果没有标识符,则执行unBindEvent() 如果有标识符,则删除指定事件处理程序,如果事件队列长度为0,执行unBindEvent() */function unBind(dom,type,fnName){ var hasQueue = dom.eventQueue && dom.eventQueue[type]; if (!hasQueue) return; if (!fnName) { unBindEvent(dom,type) } else { delete dom.eventQueue[type][fnName]; if (queueLength(dom,type) == 0) unBindEvent(dom,type); };};/*移除事件 * *@param {dom-DOM}和{type-string} *@execute 移除绑定的事件处理程序handler,并清空事件队列 *@caller unBind() */function unBindEvent(dom,type){ if (window.removeEventListener) { dom.removeEventListener(type,dom.handler[type]) } else { dom.detachEvent(type,dom.handler[type]) } delete dom.eventQueue[type];};/*判断事件队列长度 * *@param {dom-DOM}和{type-string} *@caller bind() unBind() */function queueLength(dom,type){ var index = 0; for (var length in dom.eventQueue[type]){ index++ ; } return index;};
使用方法
var oBtn = document.getElementById(tn);//绑定事件//为button同时绑定三个click事件函数//ie6-ie8下执行顺序不变bind(oBtn,click,function(){ alert(1);})bind(oBtn,click,function(){ alert(2);},myFn)bind(oBtn,click,function(){ alert(3);})//移除事件//移除所有绑定的click事件函数,支持移除匿名函数unBind(oBtn,click)//只移除标识符为myfn的事件函数unBind(oBtn,click,myFn)