JavaScript에서 이벤트를 바인딩하기 위해 addEventListener() 또는 attachmentEvent()를 사용할 때 몇 가지 사소한 문제가 있습니다.
1. addEventListener() 또는 attachmentEvent()를 사용하여 추가된 익명 함수는 제거할 수 없습니다.
var oBtn = document.getElementById('btn'); oBtn.addEventListener('click',function(){ alert('button is clicked') },false) oBtn.reomveEventListener('click',function(){ alert('button is clicked') },false) //oBtn上的事件无法移除,因为传入的是一个匿名函数
2.ie6-ie8에서는 여러 이벤트를 바인딩하기 위해 attachmentEvent()를 사용하는 역순 실행 문제가 있습니다.
var oBtn = document.getElementById('btn'); 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('btn'); //绑定事件 //为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')
위 내용은 이벤트 바인딩 문제를 해결하기 위해 캡슐화된 자바스크립트 이벤트 큐 함수 코드를 공유합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!