프런트엔드 이벤트 시스템(4)
이벤트 디스패치
먼저 jQuery를 봅시다.이벤트 디스패치 방법
dispatch: function( event ) {
// event
event = jQuery.event.fix( event );
var i, j, ret, matched, handleObj,
handlerQueue = [],
args = slice.call( arguments ),
//
handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
special = jQuery.event.special[ event.type ] || {};
// jQuery
args[0] = event;
// delegate ,
event.delegateTarget = this;
if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
return;
}
//
handlerQueue = jQuery.event.handlers.call( this, event, handlers );
//
i = 0;
while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
event.currentTarget = matched.elem;
j = 0;
while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
// Triggered event must either 1) have no namespace, or 2) have namespace(s)
// a subset or equal to those in the bound event (both can have no namespace).
if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
event.handleObj = handleObj;
event.data = handleObj.data;
ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
.apply( matched.elem, args );
if ( ret !== undefined ) {
if ( (event.result = ret) === false ) {
event.preventDefault();
event.stopPropagation();
}
}
}
}
}
// Call the postDispatch hook for the mapped type
if ( special.postDispatch ) {
special.postDispatch.call( this, event );
}
return event.result;
},
전체 코드를 통독하고 귀납해 보세요, jQuery.event.디스패치는 몇 가지 처리를 해봤어요.
이벤트 대상에 대한 복구는 이 단계에서 이벤트 대상을 얻어 jQuery의 이벤트 대상이지 원생의 대상이 아니다.여기 jQuery는 읽기만 하던 대상을 읽을 수 있고 쓸 수 있는 대상으로 바꾸어서 마음대로 조작할 수 있습니다.하지만 이벤트 대상 복구에 대해서는 다음 장에서 이벤트 복구와 함께 설명을 드리려고 합니다. 따라서 여기는 되돌아오는 jQuery의 이벤트 대상이라는 것만 알면 됩니다.
두 번째는 더 이상 말하지 않고 이벤트의 캐시를 읽었다
그러면 세 번째 지점에 오는 것도 사건 분배의 또 다른 중점이다
이벤트 대기열의 수령과 처리.
이전 버전의 jQuery에서 대기열의 생성과 처리는 디스패치에 놓여 있었지만, 지금은 대기열이 jQuery에 맡겨졌습니다.event.handlers를 생성하고 되돌려줍니다. 우선 handlerQueue가 도대체 무엇인지, 즉 jQuery에 대해 살펴보겠습니다.event.handlers로 읽으세요.
jQuery.event.handlers
handlers: function( event, handlers ) {
var i, matches, sel, handleObj,
handlerQueue = [],
delegateCount = handlers.delegateCount,
cur = event.target;
// 、
if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
// ,
for ( ; cur !== this; cur = cur.parentNode || this ) {
// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
// disabled click
if ( cur.disabled !== true || event.type !== "click" ) {
//
matches = [];
for ( i = 0; i < delegateCount; i++ ) {
handleObj = handlers[ i ];
// selector
sel = handleObj.selector + " ";
if ( matches[ sel ] === undefined ) {
//
matches[ sel ] = handleObj.needsContext ?
jQuery( sel, this ).index( cur ) >= 0 :
jQuery.find( sel, this, null, [ cur ] ).length;
}
if ( matches[ sel ] ) {
matches.push( handleObj );
}
}
if ( matches.length ) {
handlerQueue.push({ elem: cur, handlers: matches });
}
}
}
}
// ,
if ( delegateCount < handlers.length ) {
handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
}
return handlerQueue;
}
이 부분은 전체적으로 보면 비교적 복잡하니 우리 한번 정리해 봅시다.
이 부분은 먼저 이벤트 에이전트에 대한 판단과 처리를 했고 match를 이용하여 조건에 부합되는 이벤트 핸들을 선별하여 조건에 부합되는 모든 이벤트 핸들을 깊이와 얕은 순서대로 이벤트 대기열에 하나하나 넣었다.
그리고 이벤트 에이전트를 처리한 후에delegateCount로 이벤트 에이전트와 직접 귀속을 구분한 다음에 직접 귀속된 이벤트 핸들을 이벤트 대기열에 넣고 최종 이벤트 대기열을 생성합니다.이렇게 해서 최종적으로 얻은 것은 의뢰 단계가 깊을수록 앞당겨 집행되는 이벤트 대기열이다.
따라서 사건 의뢰는 이 단계에서 이미 끝났다.또한 jQuery의 이벤트 처리 메커니즘은 이런 대기열의 형식이기 때문에 앞서 제1장 말미에서 언급한 집행 순서에 대한 문제도 여기서 잘 해결되었다.
이벤트 대기열에 대한 디스패치 처리를 다시 보십시오
마지막으로 디스패치에서 이 사건 대기열을 어떻게 처리하는지 살펴봅시다.
//
i = 0;
while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
event.currentTarget = matched.elem;
j = 0;
while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
event.handleObj = handleObj;
event.data = handleObj.data;
//
ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
.apply( matched.elem, args );
// return false, event.preventDefault stopPropagation
if ( ret !== undefined ) {
if ( (event.result = ret) === false ) {
event.preventDefault();
event.stopPropagation();
}
}
}
}
}
이벤트 대기열에 대한 질서정연한 실행 (깊이와 얕음에서 그 자체로) 을 한 다음에 이 과정에서 수정된 jQuery 이벤트 대상을 통해 이벤트 대상의 속성을 동적으로 바꾸고 이벤트 핸들을 실행합니다.또한returnfalse 후 이벤트를 직접 호출합니다.preventDefault(), 및 이벤트.stopPropagation()이 처리되었습니다.
요약:
그러면 지금까지 이벤트에 대한 귀속은 이벤트의 복구 부분을 제외하고 다른 부분은 모두 읽었습니다.우리는 마지막에 가서 전체 과정을 다시 한 번 정리합시다.
그러면 다음 장에서는 jQuery 이벤트 대상의 복구와 이벤트의 복구에 대해 설명한다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.