>  기사  >  웹 프론트엔드  >  jQuery에서 Ready 함수가 작동하는 방식

jQuery에서 Ready 함수가 작동하는 방식

巴扎黑
巴扎黑원래의
2017-06-25 10:31:07856검색

jQuery는 훌륭한 스크립팅 라이브러리이며 첫 번째 버전은 2006년 1월 BarCamp NYC에서 John Resig에 의해 출시되었습니다. http://jquery.com/에서 최신 버전(현재 버전 1.8.3)을 다운로드할 수 있습니다.

jQuery를 배우는 방법은 다양합니다. 오늘은 jQuery의 Ready 함수부터 시작하겠습니다. 이 예제의 코드는 jQuery 스크립트 라이브러리에서 가져온 것입니다.

jQuery를 사용하셨다면 페이지가 준비되었을 때 실행할 수 있는 함수를 등록하는 데 사용되는 준비 함수를 사용하셨을 것입니다.

문제는 우리 페이지가 언제 준비되느냐는 것입니다.

1. onload event

이 이벤트를 처리하는 가장 기본적인 방법은 페이지의 onload 이벤트를 처리하는 방법이 많습니다. 즉, 시작 태그에 직접 작성할 수 있습니다. HTML을 통한 body 요소는 이벤트 등록으로도 사용할 수 있으며 DOM0 방식과 DOM2 방식으로 나눌 수 있습니다. 브라우저 호환성을 고려하여 아래와 같이 DOM2 모드로 작성합니다.


if (document.addEventListener) {    // A fallback to window.onload, that will always work
    window.addEventListener("load", jQuery.ready, false);    // If IE event model is used} else {    // A fallback to window.onload, that will always work
    window.attachEvent("onload", jQuery.ready);
}

2.DOMContentLoaded 이벤트

단, 페이지의 이미지 등을 포함한 모든 페이지 요소가 로드될 때까지 onload 이벤트가 발생하지 않습니다. 웹페이지에 사진이 많으면 그 효과를 짐작할 수 있습니다. 현재로서는 페이지가 초기화되지 않았고 이벤트도 등록되지 않은 상태입니다. . 너무 늦지 않았나요?

DOM의 onload 이벤트와 유사한 잘 알려진 onload 이벤트 외에도 고려해야 할 DOMContentLoaded 이벤트가 있습니다. 이 이벤트는 모든 DOM이 구문 분석될 때 트리거됩니다.

이런 방식으로 표준 기반 브라우저의 경우 이 이벤트 처리를 등록할 수도 있습니다. 이런 방식으로 로딩 완료 이벤트를 더 일찍 포착할 수 있습니다.


if (document.addEventListener) {    // Use the handy event callback
    document.addEventListener("DOMContentLoaded", DOMContentLoaded, false);    // A fallback to window.onload, that will always work
    window.addEventListener("load", jQuery.ready, false);

}

3.onreadystatechange 이벤트

브라우저가 표준이 아닌 경우 어떻게 해야 하나요?

브라우저에 document.onreadystatechange 이벤트가 있는 경우 이벤트가 발생하면 document.readyState=complete이면 DOM 트리가 로드된 것으로 간주할 수 있습니다.

그러나 이 이벤트는 그다지 안정적이지 않습니다. 예를 들어 페이지에 이미지가 있는 경우 onload 이벤트 후에 트리거될 수 있습니다. 즉, 페이지에 바이너리 리소스가 없거나 매우 많은 경우에만 올바르게 실행될 수 있습니다. 거의 없거나 캐시됩니다.


if (document.addEventListener) {    // Use the handy event callback
    document.addEventListener("DOMContentLoaded", DOMContentLoaded, false);    // A fallback to window.onload, that will always work
    window.addEventListener("load", jQuery.ready, false);    // If IE event model is used} else {    // Ensure firing before onload, maybe late but safe also for iframes
    document.attachEvent("onreadystatechange", DOMContentLoaded);    // A fallback to window.onload, that will always work
    window.attachEvent("onload", jQuery.ready);
}

DOMContentLoaded 함수는 무엇을 하고 있나요? 마지막으로 jQuery.ready 함수를 호출해야 합니다.


DOMContentLoaded = function() {    if ( document.addEventListener ) {
        document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
        jQuery.ready();
    } else if ( document.readyState === "complete" ) {        // we're here because readyState === "complete" in oldIE
        // which is good enough for us to call the dom ready!
        document.detachEvent( "onreadystatechange", DOMContentLoaded );
        jQuery.ready();
    }
}

4. doScroll 감지 방법

MSDN에는 JScript의 방법에 대해 눈에 띄지 않는 말이 있습니다. 페이지 DOM이 로드되지 않은 경우 doScroll 방법을 호출하면 예외가 발생합니다. 그런 다음 이를 역으로 사용합니다. 예외가 없으면 페이지 DOM이 로드된 것입니다.

Diego Perini는 2007년에 doScroll 메소드 호출을 사용하여 IE가 로드되었는지 감지하는 방법을 보고했습니다. 자세한 지침은 여기에서 확인할 수 있습니다.
원칙은 IE가 iframe이 아닌 경우 doScroll을 실행할 수 있는지 여부에 의해서만 DOM이 로드되었는지 지속적으로 판단할 수 있다는 것입니다. 이 예에서는 50밀리초마다 doScroll을 실행해 봅니다. 페이지가 로드되지 않을 때 doScroll을 호출하면 예외가 발생하므로 try -catch를 사용하여 예외를 포착합니다.


(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);
        }        // and execute any waiting functions        jQuery.ready();
    }
})();

5. document.readyState 상태

준비 기능을 너무 늦게 등록하면 페이지가 로드된 후 자체 준비 기능을 등록하므로 위의 확인 단계가 필요하지 않습니다. 현재 페이지의 ReadyState를 살펴보세요. 완료되면 등록할 준비 함수를 직접 실행할 수 있습니다. 그런데 ChrisS가 아주 특별한 오류 상황을 보고해 실행을 지연시켜야 합니다.

setTimeout 经常被用来做网页上的定时器,允许为它指定一个毫秒数作为间隔执行的时间。当被启动的程序需要在非常短的时间内运行,我们就会给她指定一个很小的时间数,或者需要马上执行的话,我们甚至把这个毫秒数设置为0,但事实上,setTimeout有一个最小执行时间,当指定的时间小于该时间时,浏览器会用最小允许的时间作为setTimeout的时间间隔,也就是说即使我们把setTimeout的毫秒数设置为0,被调用的程序也没有马上启动。

这个最小的时间间隔是多少呢?这和浏览器及操作系统有关。在John Resig的新书《Javascript忍者的秘密》一书中提到

    Browsers all have a 10ms minimum delay on OSX and a(approximately) 15ms delay on Windows.(在苹果机上的最小时间间隔是10毫秒,在Windows系统上的最小时间间隔大约是15毫秒)

,另外,MDC中关于setTimeout的介绍中也提到,Firefox中定义的最小时间间隔(DOM_MIN_TIMEOUT_VALUE)是10毫秒,HTML5定义的最小时间间隔是4毫秒。既然规范都是这样写的,那看来使用setTimeout是没办法再把这个最小时间间隔缩短了。

这样,通过设置为 1, 我们可以让程序在浏览器支持的最小时间间隔之后执行了。


// Catch cases where $(document).ready() is called after the browser event has already occurred.// we once tried to use readyState "interactive" here, but it caused issues like the one// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15if (document.readyState === "complete") {    // 延迟 1 毫秒之后,执行 ready 函数
    setTimeout(jQuery.ready, 1);
}

 6. 完整的代码

在 jQuery 中完整的代码如下所示。位于 jQuery 1.8.3 源代码的 #842 行。


jQuery.ready.promise = function( obj ) {    if ( !readyList ) {

        readyList = jQuery.Deferred();        // Catch cases where $(document).ready() is called after the browser event has already occurred.
        // we once tried to use readyState "interactive" here, but it caused issues like the one
        // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
        if ( document.readyState === "complete" ) {            // Handle it asynchronously to allow scripts the opportunity to delay ready
            setTimeout( jQuery.ready, 1 );        // Standards-based browsers support DOMContentLoaded
        } else if ( document.addEventListener ) {            // Use the handy event callback
            document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );            // A fallback to window.onload, that will always work
            window.addEventListener( "load", jQuery.ready, false );        // If IE event model is used
        } else {            // Ensure firing before onload, maybe late but safe also for iframes
            document.attachEvent( "onreadystatechange", DOMContentLoaded );            // A fallback to window.onload, that will always work
            window.attachEvent( "onload", jQuery.ready );            // If IE and not a frame
            // continually check to see if the document is ready
            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 );
                        }                        // and execute any waiting functions                        jQuery.ready();
                    }
                })();
            }
        }
    }    return readyList.promise( obj );
};

那么,又是谁来调用呢?当然是需要的时候,在我们调用 ready 函数的时候,才需要注册这些判断页面是否完全加载的处理,这段代码在 1.8.3 中位于代码的 #244 行,如下所示:


ready: function( fn ) {    // Add the callback    jQuery.ready.promise().done( fn );    return this;
}

在页面上引用 jQuery 脚本库之后,执行了 jQuery 的初始化函数,初始化函数中创建了 ready 函数。我们在通过 ready 函数注册事件处理之前,jQuery 完成了页面检测代码的注册。这样。当页面完全加载之后,我们注册的函数就被调用了。

위 내용은 jQuery에서 Ready 함수가 작동하는 방식의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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