> 웹 프론트엔드 > JS 튜토리얼 > javascript 크로스 브라우저 이벤트 system_javascript 기술

javascript 크로스 브라우저 이벤트 system_javascript 기술

WBOY
풀어 주다: 2016-05-16 18:31:10
원래의
1130명이 탐색했습니다.

그러나 실제로 JavaScript의 아버지는 이 모든 것을 지배할 수 없습니다. 그가 지원한 Netscape는 경쟁업체가 자사 제품을 순종적으로 사용할 수 있을 만큼 강력하지 않습니다. Microsoft는 JScript를 만들었고, 죽은 Macromedia는 ActionScript를 만들었으며 그 외에도 많은 것들이 있습니다. 이 지점은 꽤 복잡하다고 들었습니다. 그러나 브라우저의 내장 DOM 이벤트 모델을 사용하면 첫 번째 결과는 이를 사용하려면 DOM 개체, 창, 문서 또는 요소 노드를 사용해야 한다는 것입니다. 두 번째 결과는 각 브라우저가 서로 다른 지원을 갖는다는 것입니다. DOM은 이벤트 모델의 일관성을 보장할 수 없으며, 세 번째는 DOM 객체를 기반으로 하기 때문에 순환 참조가 쉽게 발생할 수 있다는 것입니다. Microsoft는 첫 번째 브라우저 전쟁에서 승리한 후 기본적으로 DOM 모델을 업데이트하지 않았습니다. w3c, ecma 및 기타 표준에 더 가까워지기 위해 지속적으로 업데이트되는 "표준 브라우저"로 두 진영으로 나뉘었습니다. 그러나 표준 브라우저는 모놀리식이 아닙니다. 예를 들어 FF는 마우스휠을 지원하지 않지만 DOMMouseScroll을 지원하며 오페라의 컨텍스트 메뉴를 제어할 수 없습니다. 우리가 직접 구현해야 합니다. 현재 두 호스트 모두 DOM2 이벤트 모델을 구현하고 있으며, 표준 모델은 addeventListener입니다. 이를 통해 동일한 요소가 동일한 유형의 여러 이벤트 콜백 함수를 바인딩할 수 있습니다. 인터넷에 있는 많은 addEvent 함수는 이를 이용하여 만들어지지만, 우선 IE의 콜백 함수는 이벤트 객체를 강제로 바인딩하지 않으며, 표준 브라우저에서는 Qiangwuqu의 첫 번째 매개변수가 이벤트 객체라고 되어 있습니다. 호출 함수는 강제 바인딩을 구현하지만 IE의 이벤트 개체도 표준 개체와 다릅니다. 또 다른 문제는 IE의 콜백 함수 실행 순서가 불규칙하고, 바인딩된 순서대로 실행하는 것이 표준입니다. 따라서 이 두 기능도 무효화됩니다. 여러 함수를 바인딩할 때는 이를 하나의 함수에 넣고 for 루프로 완성할 예정입니다.

코드 복사 코드는 다음과 같습니다.



<머리>


이벤트系统 by sai徒正美


<본문>







위의 프로세스를 검토해 보겠습니다. 이 이벤트 시스템은 실제로 Dean의 addEvent를 수정한 버전입니다.
객체를 네임스페이스로 설정합니다.
Array를 일부 확장합니다.
attachEvent 함수는 이벤트를 바인딩하는 데 사용됩니다. 구체적인 방법은 이벤트를 바인딩해야 하는 개체에 이벤트 속성을 설정한 다음 이벤트 유형에 따라 콜백 함수를 배치하는 것입니다. 때로는 동일한 요소에 2개 이상의 onclick 이벤트를 바인딩할 수 있으므로 해당 이벤트는 이벤트여야 합니다. 배열. 마지막으로 DOM0의 원래 방법을 사용하여 onXXXX 속성을 추가합니다.
detachEvent 함수는 이벤트에서 해당 유형의 배열 요소를 제거하는 이벤트 언로드에 사용됩니다.
handleEvent는 콜백 함수를 실행합니다. onXXXX 형식으로 전역 함수를 바인딩했습니다. 그 함수는 이벤트 객체를 획득하고 수정한 다음 이 이벤트 유형에 해당하는 모든 콜백 함수를 획득한 다음 이벤트 객체를 첫 번째 매개변수로 사용하여 차례로 실행하는 것입니다. 마지막 단계는 버블링을 처리하는 것입니다.
fixEvent 수정 이벤트 개체입니다. 기본적으로 IE가 표준 브라우저를 가지도록 만드는 방법에는 두 가지가 있습니다.
일반 용도로는 충분합니다. 하지만 완벽함을 추구한다면. 우리는 아직 사용할 것이 많습니다. 우선, 거대한 이벤트 대상을 요소에 두는 것은 매우 부적절하며 이는 중앙 집중식 관리에 도움이 되지 않습니다. 둘째, fixEvent가 철저하지 않습니다. target 및 pageX/Y와 같은 표준 브라우저의 속성은 IE에서 여전히 사용할 수 없습니다.
첫 번째는 handlerEvent 함수입니다. 이제 표준 브라우저와 IE의 이벤트 개체가 호출될 때마다 IE에 대한 currentTarget 값도 수정되어야 합니다.
코드 복사 코드는 다음과 같습니다.

dom.handleEvent = function(event) {
이벤트 = 이벤트 || window.event
event = dom.fixEvent(event);
event.currentTarget = this;//Fix currentTarget
var returnValue =
var handlers = this.events [event.type];
for(var i=0,n=handlers.length;iif (handlers[i](event) === false) {
returnValue = false;
}
}
return returnValue;
}

fixEvent 함수의 새 버전을 처음 소개합니다. 나에게 jQuery 의사 이벤트 객체에서 훔친 것입니다.
코드 복사 코드는 다음과 같습니다.

dom.oneObject = function(arr,val){
var result = {},value = val !== 정의되지 않음 ? 값:1;
for(var i=0,n=arr.length;i결과[arr[i]] = value;
반환 결과;
};
dom.mixin = function(result, source) {
if (arguments.length === 1) {
source = result;
결과 = 돔;
}
if (결과 && 소스 ){
for(소스의 var 키)
source.hasOwnProperty(key) && (결과[키] = 소스[키]);
}
if(arguments.length > 2 ){
var other = [].slice.call(arguments,2);
for(var i=0,n=others.length;iresult =args.callee(result,others[i]);
}
}
결과 반환;
}
var MouseEventOne = dom.oneObject(["click","dblclick","mousedown",
"mousemove","mouseout", "mouseover","mouseup"],"[object 마우스이벤트]");
var HTMLEventOne = dom.oneObject(["abort","blur","change","error","focus",
"load","reset","resize","scroll", "선택","제출","언로드"],"[개체 이벤트]");
var KeyboardEventOne = dom.oneObject(["keyup","keydown","keypress",],
"[object KeyboardEvent]");
var EventMap = dom.mixin({},MouseEventOne,HTMLEventOne,KeyboardEventOne)
var fn = "prototype";
dom.Event = function( src ) {
if ( !this.preventDefault ) {
return new dom.Event[fn].init( src );
}
};
함수 returnFalse() {
false를 반환;
}
function returnTrue() {
return true;
}
// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-bound.html
dom.Event[fn ] = {
init:function(src){
//如果传入的是事件对象
if ( src && src.type ) {
this.originalEvent = src;
this.type = src.type;
//如果传入的是事件类型
} else {
this.type = src;
}
this.timeStamp = new Date().valueOf();
이[ "expando" ] = true;
},
//http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/events.html#Conformance
toString:function(){
eventMap[this.type] 반환 || "[객체 이벤트]"
},
preventDefault: function() {
this.isDefaultPrevented = returnTrue;
var e = this.originalEvent;
if ( !e ) {
return;
}
// 如果存재preventDefault 那么就调用它
if ( e.preventDefault ) {
e.preventDefault();
}
// 如果存재returnValue 那么就将它设为false
e.returnValue = false;
},
stopPropagation: function() {
this.isPropagationStopped = returnTrue;
var e = this.originalEvent;
if ( !e ) {
return;
}
// 如果存재preventDefault 那么就调用它
if ( e.stopPropagation ) {
e.stopPropagation();
}
// 如果存재returnValue 那么就将它设为true
e.cancelBubble = true;
},
stopImmediatePropagation: function() {
this.isImmediatePropagationStopped = returnTrue;
this.stopPropagation();
},
isDefaultPrevented: returnFalse,
isPropagationStopped: returnFalse,
isImmediatePropagationStopped: returnFalse
};
dom.Event[fn].init[fn] = dom.Event[fn];

W3C事个构造函数只实现了W3C事件模型 의 少许型 少许哪, 那些属性去了哪? 不急, 我们了函数只实现了W3C事?实现它们。为了区别원생사件对象与伪事件对象,我们在它上面添加了一个expando属性。
复aze代码 代码如下:

var 버튼맵 = {
1:1,
4:2,
2:3
}
dom.fixEvent = 함수(이벤트){
if ( event[ "expando" ] ) {
return event;
}
var originalEvent = event
event = dom.Event(originalEvent)
for(var prop in originalEvent){
if(typeof originalEvent[prop] !== "function"){
event[prop] = originalEvent[prop]
}
}
//대상 속성이 존재하지 않는 경우, 설정하세요
if ( !event.target ) {
event.target = event.srcElement || document
}
//이벤트 소스 객체가 텍스트 노드인 경우, 상위 요소 배치
if ( event.target.nodeType === 3 ) {
event.target = event.target.parentNode;
}
//관련 타겟 속성이 존재하지 않는 경우 하나 추가하세요
if ( !event.관련Target && event.fromElement ) {
event.관련Target = event.fromElement === event.target ? event.toElement : event.fromElement
//존재하지 않는 경우 pageX/Y는 clientX/Y와 결합되어 쌍을 만듭니다.
if ( event.pageX == null && event.clientX != null ) {
var doc = document.documentElement , body = document.body;
event.pageX = event.clientX (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = event.clientY (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); 🎜>}
// 키보드 이벤트는 어떤 이벤트를 추가합니다
if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
event.which = event.charCode || event.keyCode;
}
// Mac이 아닌 브라우저에 MetaKey 추가(PC의 경우 Ctrl 사용, Mac의 경우 Meta 사용)
if ( !event .metaKey && event.ctrlKey ) {
event.metaKey = event.ctrlKey;
}
// 마우스 이벤트에서 어떤 키가 눌렸는지 확인합니다. 1 === left 2 === middle; 3 === 오른쪽
if ( !event.which && event.button !== undefine ) {
event.which = 버튼맵[event.button]
}
return event; }


milli 모든 클래스 라이브러리 중에서 jQuery의 메소드가 추출하기에 가장 좋으므로 주저하지 말고 jQuery의 메소드를 복사하세요.
이제 우리는 기사 중간에 제기된 두 가지 질문 중 하나를 기본적으로 해결했습니다. 첫 번째 문제를 해결하려면 캐싱 시스템을 도입해야 합니다. 이는 다음 섹션에 남겨집니다.




[Ctrl A 모두 선택 참고: 외부 J를 도입해야 하는 경우 실행하려면 새로 고쳐야 합니다 ]
관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿