jQuery 소스 시리즈(11) 이벤트 총체 개요

나의 칼럼에 와서 시리즈의 문장을 보는 것을 환영합니다.
이번 내용은 jQuery에 대한 사건 의뢰를 소개하는 내용입니다.그런데 그 전에 JS에서 사건 의뢰와 거품을 알아볼 필요가 있어요. 저도 비슷한 블로그를 썼어요. 사건 거품과 포획.
JS 이벤트에서 가져오기
사건은 JSDOM에서 가장 활력이 넘치는 내용입니다. 수시로 DOM의 변화를 감청하고 신속하게 반응할 수 있습니다. 만약에 JS의 사건을 잘 모르면 관련 소개문을 보고 JQuery의 사건 의뢰를 직접 보면 머리가 커질 것입니다.
사건의 처리 순서는 두 가지 부분으로 나뉘는데 하나는 포획 부분이고 하나는 거품이 생기는 부분이다. 다른 사람의 그림을 빌려 쓴다.
처리도 포함하면 전체 사건은 포획 단계, 목표 처리 단계와 거품 단계로 세 단계로 나뉜다.포획 단계는 바깥에서 안으로 target을 찾고, 거품이 생기는 단계는 안쪽에서 바깥쪽으로 뿌리 결점까지 찾습니다.이것은 단지 하나의 사건일 뿐이다. 이 세 단계에 더 많은 사건이 삽입되어 있을 때 사건의 집행 순서를 고려해야 한다.
한편, jQuery 이벤트 의뢰의 개념: 이벤트 목표 자체가 이벤트를 처리하지 않고 부모 요소나 조상 요소나 뿌리 요소에 의뢰하고 이벤트의 거품성(내향외)을 빌려 최종 처리 이벤트를 달성한다.
jQuery의 이벤트 최적화
우선 귀속 이벤트가 많을수록 브라우저 메모리가 많이 차지할수록 성능에 간접적으로 영향을 미친다는 것을 알아야 한다.그리고 aax가 나타나면 국부 리셋으로 다시 귀속 이벤트가 발생합니다.
이벤트 의뢰를 사용하면 상기에서 가져온 문제를 해결할 수 있다. 사건의 거품을 빌릴 수 있다. 특히 한 부모 원소의 하위 원소가 너무 많고 하위 원소가 연결된 사건이 매우 많을 때 의뢰 사건의 역할이 나타난다.
저는 JS의 성능 문제를 비교하는 데 능하지 않습니다. 관심이 있으면 이 글에서 사건 의뢰 성능에 대한 디자인과 비교를 보십시오.심도 있는 이해 - 사건 의뢰.
초기의 jQuery 버전에서는 .delegate(),.bind(),.live() 등 방법으로 사건 감청을 실현했다. 물론 .click() 방법도 포함되었다. jQuery의 발전에 따라 라이브 방법처럼 jQuery에서 명확하게 삭제되었고 나머지 방법, 예를 들어bind 방법도 3.0 이후의 버전에서 계속 삭제되었다. 대신.on() 방법도 포함된다.그리고 나머지 다른 방법은 모두 on 방법을 통해 간접적으로 이루어진 것이기 때문에 소개하면 on의 원본 코드만 보면 된다.
n 함수는 jQuery에서 사용하는 방법도 간단합니다. .on( events [, selector ] [, data ], handler(eventObject) ) 이벤트는 연결된 이벤트를 나타냅니다. 예를 들어'click'이나'click mouseleave'는 selector와 데이터가 선택할 수 있습니다. 이벤트를 연결할 요소와 실행할 데이터를 나타냅니다.handler는 이벤트 실행 함수를 나타냅니다.
ff 함수의 사용법.off( events [, selector ] [, handler ] ), 이벤트는 제거할 이벤트를 나타내고,selector는 선택된dom를 나타내며,handler는 이벤트 처리 함수를 나타낸다.그리고 더 잔인한 것은 .off() 매개 변수를 받아들이지 않고 모든 on 귀속 함수를 제거하는 것을 의미한다.
on off 함수 소스
비록 내가 분석한 원본 코드는 jQuery 3.1.1이었지만 이때bind와delegate 함수는 원본 코드에서 제거되지 않았다. 먼저 그들이 어떻게 on을 호출하는지 보자.
jQuery.fn.extend( {
  bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
  },
  unbind: function( types, fn ) {
    return this.off( types, null, fn );
  },
  delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
  },
  undelegate: function( selector, types, fn ) {
    // ( namespace ) or ( selector, types [, fn] )
    return arguments.length === 1 ?
      this.off( selector, "**" ) :
      this.off( types, selector || "**", fn );
  }
} );

모두 온과 오프 두 함수에 의해 처리되었다는 것을 알 수 있다.
jQuery.fn.extend( {
  on: function (types, selector, data, fn) {
    // on         on   
    return on(this, types, selector, data, fn);
  }
} );
function on( elem, types, selector, data, fn, one ) {
  var origFn, type;

  //    object    
  if ( typeof types === "object" ) {

    // ( types-Object, selector, data )
    if ( typeof selector !== "string" ) {

      // ( types-Object, data )
      data = data || selector;
      selector = undefined;
    }
    //      object     
    for ( type in types ) {
      on( elem, type, selector, data, types[ type ], one );
    }
    return elem;
  }
  //         
  if ( data == null && fn == null ) {

    // ( types, fn )
    fn = selector;
    data = selector = undefined;
  } else if ( fn == null ) {
    if ( typeof selector === "string" ) {

      // ( types, selector, fn )
      fn = data;
      data = undefined;
    } else {

      // ( types, data, fn )
      fn = data;
      data = selector;
      selector = undefined;
    }
  }
  if ( fn === false ) {
    // returnFalse       false    
    fn = returnFalse;
  } else if ( !fn ) {
    return elem;
  }

  if ( one === 1 ) {
    origFn = fn;
    fn = function( event ) {

      // Can use an empty set, since event contains the info
      jQuery().off( event );
      return origFn.apply( this, arguments );
    };

    // Use same guid so caller can remove using origFn
    fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
  }
  return elem.each( function() {
    //   
    jQuery.event.add( this, types, fn, data, selector );
  } );
}

네, 잘못 보지 않았습니다. 이 전역의 on 함수는 사실 매개 변수를 교정하는 역할을 했을 뿐입니다. 진정한 큰 머리는 다음과 같습니다.
jQuery.event = {
  global = {},
  add: function(){...},
  remove: function(){...},
  dispatch: function(){...},
  handlers: function(){...},
  addProp: function(){...},
  fix: function(){...},
  special: function(){...}
}

off 함수:
jQuery.fn.off = function (types, selector, fn) {
  var handleObj, type;
  if (types && types.preventDefault && types.handleObj) {
    // ( event )  dispatched jQuery.Event
    handleObj = types.handleObj;
    jQuery(types.delegateTarget).off(
      handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
      handleObj.selector,
      handleObj.handler
    );
    return this;
  }
  if (typeof types === "object") {
    // ( types-object [, selector] )
    for (type in types) {
      this.off(type, selector, types[type]);
    }
    return this;
  }
  if (selector === false || typeof selector === "function") {
    // ( types [, fn] )
    fn = selector;
    selector = undefined;
  }
  if (fn === false) {
    fn = returnFalse;
  }
  return this.each(function() {
    //   
    jQuery.event.remove(this, types, fn, selector);
  });
}

총결산
이를 통해 알 수 있듯이 jQuery는 매개 변수의 방종으로 인해 처리하기가 매우 복잡하지만 사용자에게 매우 편리하다.
위탁 사건도 일부 부족을 가져왔다. 예를 들어 일부 사건은 거품을 일으킬 수 없고load,submit 등은 관리를 강화하는 등 복잡하고 사용자가 사건을 촉발하는 것을 모의하기 어렵다.
참고 자료
jQuery 2.0.3 원본 분석 이벤트 귀속-bind/live/delegate/on깊이 이해-이벤트 의뢰.on()
본문의github에 있는 원본 주소입니다. star에 오신 것을 환영합니다.
나의 블로그에 와서 교류하는 것을 환영합니다.

좋은 웹페이지 즐겨찾기