>  기사  >  웹 프론트엔드  >  Jquery1.9.1 소스코드 분석 시리즈 (6) Delay 객체 적용 jQuery.ready_jquery

Jquery1.9.1 소스코드 분석 시리즈 (6) Delay 객체 적용 jQuery.ready_jquery

WBOY
WBOY원래의
2016-05-16 15:30:031148검색

jQuery 초기화 함수인 jQuery.fn.init에 브랜치가 있다는 걸 아직도 기억하시나요

//document ready简便写法$(function(){…})
} else if ( jQuery.isFunction( selector ) ) {
 return rootjQuery.ready( selector );
}
  所以$(fn)===$(document).ready(fn)。
  来看一下jQuery.fn.ready的源码
ready: function( fn ) {
 // Add the callback
 jQuery.ready.promise().done( fn );
 return this;
}

jQuery.ready.promise 함수에 지연이 설정되어 있고 지연 객체가 해결되면 fn 함수가 실행되는 것은 당연합니다.

주요 처리 흐름:

지연 객체를 생성하고 문서 준비가 완료된 후 처리 이벤트를 지연 객체의 성공 이벤트 목록에 추가합니다.

jQuery.ready.promise = function( obj ) {
  if ( !readyList ) {
    readyList = jQuery.Deferred();
    ...
  }
 return readyList.promise( obj );
}

문서 준비 상태에 대한 수신 기능 추가(jQuery.ready.promise 함수 조각)

 //标准浏览器支持DOMContentLoaded事件
 } else if ( document.addEventListener ) {
   //绑定DOMContentLoaded事件和响应函数,响应函数会解决延时
   document.addEventListener( "DOMContentLoaded", completed, false );
   //回退到window.onload事件绑定,所有的浏览器都支持
   window.addEventListener( "load", completed, false );
 //如果是IE事件模型
 } else {
   //确保在onload之前执行延时,可能时间比较迟,但是对于iframes来说比较安全
   document.attachEvent( "onreadystatechange", completed );
   //回退到window.onload事件绑定,所有的浏览器都支持
   window.attachEvent( "onload", completed );
   //如果IE并且不是一个frame
   //不断地检查,看是否该文件已准备就绪
   var top = false;
   try {
    top = window.frameElement == null && document.documentElement;
   } catch(e) {}
   if ( top && top.doScroll ) {
    (function doScrollCheck() {
     if ( !jQuery.isReady ) {
      try {
       // Use the trick by Diego Perini
       // http://javascript.nwbox.com/IEContentLoaded/
       top.doScroll("left");
      } catch(e) {
       return setTimeout( doScrollCheck, 50 );
      }
      //移除之前绑定的事件
      detach();
      //执行延迟
      jQuery.ready();
     }
    })();
   }
  }

문서가 준비된 것으로 감지되면 jQuery.ready를 호출하여 지연 객체의 성공 콜백 목록을 실행합니다. 즉, jQuery.ready(fn) [또는 jQuery(fn)]를 통해 추가된 모든 함수 fn입니다.

//ready事件处理函数
completed = function( event ) {
 // readyState === "complete"在老版本IE上适用
 if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
  detach();
  jQuery.ready();
 }
},
//清除ready事件绑定
detach = function() {
 if ( document.addEventListener ) {
  document.removeEventListener( "DOMContentLoaded", completed, false );
  window.removeEventListener( "load", completed, false );
 } else {
  document.detachEvent( "onreadystatechange", completed );
  window.detachEvent( "onload", completed );
 }
};

//处理当DOM准备完成
jQuery.ready: function( wait ) {      
 ...        
 //设置DOM已经准备好的标志      
 jQuery.isReady = true;   
 ...   
 //执行绑定的延时事件   
 readyList.resolveWith( document, [ jQuery ] );   
 //触发任何绑定的就绪事件   
 if ( jQuery.fn.trigger ) {     
  jQuery( document ).trigger("ready").off("ready");   
 } 
}

이것이 전체 과정입니다. 정리해야 할 몇 가지 작은 지식 포인트가 있습니다.

a. 문서 로딩 상태 document.readyState

Document.readyState는 문서 로딩 상태를 결정하는 데 사용됩니다. 가능한 값은 다음과 같습니다.

 0-uninitialized: XML 객체가 생성되지만 파일이 로드되지 않습니다.
1-loading: 로딩 프로그램이 진행 중이지만 파일 분석이 아직 시작되지 않았습니다.
2-로드: 일부 파일이 로드되고 구문 분석되었지만 개체 모델이 아직 적용되지 않았습니다.
3-대화형: 로드된 파일의 일부에만 유효합니다. 이 경우 개체 모델은 유효하지만 읽기 전용입니다.
4-complete: 파일이 완전히 로드되었습니다. 이는 로드가 성공했음을 의미합니다.

예:

document.onreadystatechange = stateChange;//当页面加载状态改变的时候执行这个方法.
function stateChange() {   
  if(document.readyState == "complete"){ //当页面加载状态为完全结束时进入     
    alert("文档加载成功")   
  } 
}

하지만 이전 버전의 Firefox에서는 document.readyState를 지원하지 않습니다. [최신 Firefox에서는 이미 지원하고 있습니다.] 따라서 모든 브라우저와 호환되려면 두 가지 상황에서 모니터링 문서 작성을 진행해야 합니다.

- 표준 브라우저는 addEventListener를 사용하여 DOMContentLoaded를 추가하고 리스너를 로드하며 모든 이벤트가 트리거될 수 있습니다.

- 이전 버전의 IE 브라우저는 attachmentEvent를 사용하여 onreadystatechange 및 onload를 모니터에 추가하고, 어느 것이든 트리거되며, onreadystatechange 시 document.readyState === "complete"입니다.

jQuery에서는 이렇게 처리합니다

jQuery.ready.promise = function(){
  ...
  //标准浏览器支持DOMContentLoaded事件
  else if ( document.addEventListener ) {
   //绑定DOMContentLoaded事件和响应函数,响应函数会解决延时
   document.addEventListener( "DOMContentLoaded", completed, false );
   //回退到window.onload事件绑定,所有的浏览器都支持
   window.addEventListener( "load", completed, false );
 //如果是IE事件模型
 } else {
   //确保在onload之前执行延时,可能时间比较迟,但是对于iframes来说比较安全
   document.attachEvent( "onreadystatechange", completed );
   //回退到window.onload事件绑定,所有的浏览器都支持
   window.attachEvent( "onload", completed );
       ...
  }
}
//ready事件处理函数
completed = function( event ) {
 // readyState === "complete"在老版本IE上适用
 if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
  detach();
  jQuery.ready();
 }
}

 b.doScroll이 문서 로딩 완료를 감지합니다

이것은 IE가 로드되었는지 감지하기 위해 Diego Perini가 발견한 방법입니다. 상세링크

페이지 DOM이 로드되지 않은 경우 doScroll 메소드 호출 시 예외가 발생하는 것이 원칙입니다. 그러면 예외 발생 여부를 지속적으로 확인하여 문서가 로드되었는지 알 수 있습니다. 예외가 발생하지 않으면 문서 로딩이 완료된 것입니다. ~

 (function doScrollCheck() {
     if ( !jQuery.isReady ) {
      try {
       // Use the trick by Diego Perini
       // http://javascript.nwbox.com/IEContentLoaded/
       top.doScroll("left");
      } catch(e) {
       return setTimeout( doScrollCheck, 50 );
      }
      //移除之前绑定的事件
      detach();
      //执行延迟
      jQuery.ready();
     }
    })();
위 내용은 Jquery1.9.1 소스코드 분석 시리즈의 전체 내용입니다. (6) Script House 편집자가 소개한 지연된 객체 적용을 위한 jQuery.ready가 마음에 드셨으면 좋겠습니다.

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