>웹 프론트엔드 >JS 튜토리얼 >JavaScript는 크로스 브라우저 이벤트 처리 메커니즘을 생성합니다. [Blue-Dream 제작]_javascript 기술

JavaScript는 크로스 브라우저 이벤트 처리 메커니즘을 생성합니다. [Blue-Dream 제작]_javascript 기술

WBOY
WBOY원래의
2016-05-16 18:23:211224검색

클래스 라이브러리를 사용하면 호환성 문제를 해결하는 것이 더 쉽습니다. 그런데 그 메커니즘은 무엇인지 하나씩 설명하겠습니다.
먼저 DOM Level2는 이벤트 처리를 위해

addEventListenerremoveEventListener라는 두 가지 함수를 정의하며, 둘 다 EventTarget 인터페이스에서 제공됩니다. 🎜>

코드 복사 코드는 다음과 같습니다. element.addEventListener(eventName, Listener, useCapture)
element .removeEventListener(eventName, Listener, useCapture);


EventTarget 인터페이스는 일반적으로 Node 또는 Window 인터페이스에서 구현됩니다.
예를 들면 다음과 같습니다. window는 addEventListener를 통해 리스너를 추가할 수도 있습니다.



코드 복사 코드는 다음과 같습니다. 함수 loadHandler() {
console.log ('페이지가 로드되었습니다!')
}
window.addEventListener('load', loadHandler, false)


제거 중 제거된 핸들과 추가된 핸들은 함수를 참조한다는 점만 참고하세요.
window.removeEventListener('load', loadHandler, false); 그런 다음 이벤트를 추정합니다.
그러나 IE는 고유하기 때문에 addEventListener 및 RemoveEventListener를 대체하기 위해 두 가지 함수가 MSDHTML DOM을 통해 정의됩니다. 기능 간의 많은 차이점으로 인해 전체 이벤트 메커니즘이 매우 복잡해졌습니다.
그래서 우리가 실제로 해야 할 일은 IE 브라우저와 w3c 표준 간의 이벤트 처리 차이점을 처리하는 것입니다.

모니터링을 추가하고 리스너를 제거하려면




코드 복사

코드는 다음과 같습니다. function loadHandler() { alert('페이지가 로드되었습니다!') } window.attachEvent('onload', loadHandler) // 리스너 추가
window.detachEvent ('onload', loadHandler); // 모니터링 제거


표면적으로 보면 IE와 w3c의 두 가지 차이점을 볼 수 있습니다.
앞에 "on" 접두사가 있습니다.
2. useCapture의 세 번째 매개변수가 제거되었습니다.
사실 실제 차이점은 나중에 계속해서 분석할 예정입니다. 공통 함수



코드 복사

코드는 다음과 같습니다. function addListener(element, eventName , handler) { if (element.addEventListener) { element.addEventListener(eventName, handler, false) }
else if (element.attachEvent) {
element.attachEvent( 'on' eventName, handler);
}
else {
element['on' eventName] = handler
}
}
function RemoveListener(element, eventName, handler) {
if (element.addEventListener) {
element.removeEventListener(eventName, handler, false)
}
else if (element.detachEvent) {
element.detachEvent('on' eventName, handler);
else {
element['on' eventName] = null
}
}


두 가지 사항에 유의하세요. 위 기능에 대해:
1. 먼저 이 분기에 대한 w3c 표준을 측정하는 것이 가장 좋습니다. 왜냐하면 IE가 점차 표준에 가까워지고 있기 때문입니다.
2. EventListener를 지원(추가/제거)하거나 이벤트 브라우저(첨부)/분리를 지원하지 않습니다.

성능 최적화
위 기능의 경우 "런타임" 모니터링을 사용합니다. 즉, 각 바인딩 이벤트에는 분기가 필요합니다. 모니터링. 호환되는 기능을 확인하기 위해 "실행 전"으로 변경할 수 있습니다. 매번 모니터링할 필요는 없습니다.
이런 방식으로 여기서는 document.documentElement를 선택해야 합니다. . document.body를 사용하지 않는 이유는 문서가 준비되지 않은 상태에서 document.documentElement가 이미 존재하기 때문입니다.
이런 식으로 함수는




코드 복사


코드는 다음과 같습니다.

var addListener, RemoveListener,
/* 테스트 요소 */
docEl = document.documentElement;
// addListener
if (docEl.addEventListener) {
/* `addEventListener`가 테스트 요소에 존재하는 경우 `addEventListener`를 사용할 함수를 정의합니다. */
addListener = 함수(요소, eventName, handler) {
element.addEventListener(eventName, handler, false);
};
}
else if (docEl.attachEvent) {
/* `attachEvent`가 테스트 요소에 존재하는 경우 `attachEvent`를 사용할 함수를 정의합니다. */
addListener = 함수(요소, 이벤트 이름, 핸들러 ) {
element.attachEvent('on' eventName, handler);
};
}
else {
/* 테스트 요소에 메서드가 모두 없으면 대체 전략에 대한 함수 정의 */
addListener = function (element, eventName, handler) {
element['on ' eventName] = 핸들러;
};
}
//removeListener
if (docEl.removeEventListener) {
removeListener = function (element, eventName, handler) {
element.removeEventListener(eventName, handler, false);
};
}
else if (docEl.detachEvent) {
removeListener = function (element, eventName, handler) {
element.detachEvent('on' eventName, handler);
};
}
else {
removeListener = 함수(요소, 이벤트 이름, 핸들러) {
요소['on' eventName] = null;
};
}

这样就避免了每次绑정관광需要判断.
상위면에는 현대적인 가구가 있습니다. 더 많은 양의 데이터를 사용하려면 문서 추가/제거 방법을 사용하세요.那么element就一定具备(虽然大多数情况如此).但这显然是不够안전.
안전하지 않은 보안
하단면에는 보안이 없습니다.
复system代码 代码如下:

// Internet Explorer
var xhr = new ActiveXObject('Microsoft.XMLHTTP');
if (xhr.open) { } // 오류
var element = document.createElement('p');
if (element.offsetParent) { } // 오류

如: 재IE7下 typeof xhr.open === '알 수 없음'. 详细可参考기능 감지
所以我们提倡的检测方式是
复代码 下:
var isHostMethod = function (object, methodName) {
var t = typeof object[methodName];
return ((t === '함수' || t === '객체') && !!object[methodName]) || t === '알 수 없음';
};

这样我们上面的优化函数.再次改进成这样

复主代码 代码아래:
var addListener, docEl = document.documentElement;
if (isHostMethod(docEl, 'addEventListener')) {
/* ... */
}
else if (isHostMethod(docEl, 'attachEvent')) {
/* ... */
}
else {
/* ... */
}

丢失的 this指针
this指针的处理.IE w3c를 출시하면 w3c에서 다운로드할 수 있는 DOM 리소스를 확인할 수 있습니다. 而IE下却总是指向창.

复主代码 代码如下:
// IE
document.body.attachEvent( 'onclick', function () {
alert(this === window); // true
alert(this === document.body); // false
});
// W3C
document.body.addEventListener('onclick', function () {
alert(this === window); // false
alert(this === document.body ); // 참
});

这个问题修正起来也不算麻烦

复主代码 代码如下:
if (isHostMethod(docEl, 'addEventListener')) {
/* ... */
}
else if (isHostMethod(docEl, 'attachEvent')) {
addListener = function (element, eventName, handler) {
element.attachEvent('on' eventName, function () {
handler.call(element, window.event);
});
};
}
else {
/* ... */
}


랩퍼 함수만 사용하면 됩니다. 그런 다음 호출을 사용하여 내부적으로 핸들러의 포인터를 다시 수정해야 합니다. 사실 여기에서도 비밀리에 수정된 문제가 있다는 것을 모두가 알아차렸을 것입니다. 는 첫 번째 함수를 통과하지 않고 전역에 남아 있으므로 event = event ||와 같은 코드를 자주 작성합니다.
이러한 주요 문제를 수정했습니다. 잠시 멈추고 간단한 테스트를 할 수 있습니다.
1. 브라우저 간 호환성 2. 이 포인터가 가리키는 호환성

테스트 코드는 다음과 같습니다.
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.