배경
addEventListener() 또는 attachmentEvent()를 사용하여 JavaScript에서 이벤트를 바인딩할 때 몇 가지 사소한 문제가 있습니다.
1. addEventListener() 또는 attachmentEvent()를 사용하여 추가된 익명 함수는 제거할 수 없습니다.
var oBtn = document.getElementById('btn');
oBtn.addEventListener('click',function(){
Alert('버튼이 클릭되었습니다')
},false)
oBtn.reomveEventListener('click', function() {
Alert('버튼을 클릭했습니다')
},false)
//
에 익명 함수가 전달되었기 때문에 oBtn의 이벤트를 제거할 수 없습니다. 2. ie6 - IE8에서는 여러 이벤트를 바인딩하기 위해 attachmentEvent()를 사용할 때 역순으로 실행되는 문제가 있습니다.
var oBtn = document.getElementById('btn ');
oBtn.attachEvent('onclick',function(){
경보(1)
})
oBtn.attachEvent('onclick',function() {
경보(2)
})
oBtn.attachEvent('onclick',function(){
경보(3)
})
//ie9 다음 실행 순서 1 , 2, 3
//ie6-ie8의 실행 순서 3, 2, 1
문제 해결
향후 재사용이 가능하도록 크로스 브라우저 이벤트 바인딩 모듈을 작성하는 동시에 어필 문제도 해결하고 싶습니다. JQuery는 이 문제를 해결하기 위해 내부적으로 이벤트 큐와 데이터 캐싱 메커니즘을 사용합니다. 관련 소스 코드를 살펴본 결과 실제로 몇 가지 방법을 시도해 보고 해결했습니다. 제가 게시한 코드 조각은 원래 객체 지향 방식으로 작성되었으므로 복잡해지는 것을 원하지 않아 함수로 변경했습니다.
/*이벤트 바인딩을 위한 인터페이스
*
*@param {dom-DOM} 및 {type-string} 및 {fn-function} 선택적 매개변수 {fnName-string}
* @execute 이벤트 큐를 생성하고 DOM 객체 속성에 추가합니다.
이벤트 핸들러(함수)를 이벤트 큐에 추가합니다.
이벤트 핸들러에 식별자를 추가하여 지정된 이벤트 핸들러를 삭제할 수 있습니다.
*/
함수 바인드(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]) binEvent(dom,type);
};
/*Bind 이벤트
*
*@param {dom-DOM} 및 {type-string }
*@execute 이벤트를 한 번만 바인딩하며, 핸들러는 실행 이벤트 대기열의 이벤트 핸들러(함수)를 순회하는 데 사용됩니다.
*@caller 바인딩()
*/
functionbinEvent(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 경계 제거 이벤트 핸들러 핸들러 및 이벤트 큐 지우기
*@caller unBind()
*/
function unBindEvent(dom,type){
if (window.removeEventListener) {
dom.removeEventListener( type,dom.handler[type])
}
else {
dom.detachEvent(type,dom.handler[type])
}
dom.eventQueue[type 삭제 ];
};
/*이벤트 큐 길이 판단
*
*@param {dom-DOM} 및 {type-string}
*@caller 바인딩() unBind ()
*/
function queueLength(dom,type){
var index = 0;
for (var length in dom.eventQueue[type]){
index ;
}
인덱스 반환;
};
사용방법
코드 복사
코드는 다음과 같습니다.
var oBtn = document.getElementById('btn');
//이벤트 바인딩
//버튼에 대한 세 개의 클릭 이벤트 함수를 동시에 바인딩
//ie6 -ie8
bind(oBtn,'click',function(){
Alert(1);
})
bind(oBtn,'click',function()에서 실행 순서는 변경되지 않습니다. {
경보(2);
},'myFn')
bind(oBtn,'click',function(){
경보(3);
})
//이벤트 제거
//바운드 클릭 이벤트 함수 모두 제거, 익명 함수 제거 지원
unBind(oBtn,'click')
//식별자만 제거 myfn의 이벤트 함수용
unBind(oBtn,'click','myFn')
프로그래밍 아이디어
프로그램의 주요 아이디어는 이벤트 큐를 dom 요소 객체의 속성으로 사용하고 이를 전역 환경을 오염시키지 않고 dom 요소에 추가하는 것입니다. 이를 통해 여러 이벤트 함수의 데이터 바인딩 문제를 해결할 수 있습니다. 다양한 DOM 요소에 대한 다양한 이벤트 유형.
//dom 요소의 이벤트 큐
dom {
eventQueue : {
'클릭' : {
fnQueue1 : 기능,
myfn : 기능,
fnQueue3 : 기능
}
'mouseover' : {
fnQueue1 : 함수,
fnQueue2 : 함수
}
}
}
매번 해당 이벤트 유형의 이벤트 큐에 이벤트 함수를 추가하고, 이벤트를 한 번만 바인딩합니다. 이벤트가 트리거되면 핸들러 이벤트 함수가 실행되고, 핸들러는 이벤트 큐에 있는 이벤트 함수를 순회하여 실행합니다.
unBind()는 식별자가 전달되지 않은 경우 바인딩된 모든 이벤트 함수를 제거하고, 익명 함수 제거를 지원하며, 식별자가 있는 경우 지정된 이벤트 함수를 제거합니다.
프로그램 로직은 복잡하지 않으며, 버그 및 성능 문제가 있을 수 있습니다.