jQuery없이 $ (document) .ready에 해당


2016

을 사용하는 스크립트가 $(document).ready있지만 jQuery의 다른 것을 사용하지 않습니다. jQuery 종속성을 제거하여 밝게하고 싶습니다.

$(document).readyjQuery를 사용하지 않고 어떻게 자신의 기능을 구현할 수 있습니까? 모든 이미지, 프레임 등이로드 된 후 화재가 발생 window.onload하므로 사용 이 동일하지 않다는 것을 알고 있습니다 window.onload.


296
... 그리고 확실히 같은 기능은 아닙니다.
Joel Mueller

40
이 답변에서 알 수 있듯이 jQuery에서 원하는 것이 모두 인 경우 $(document).ready맨 위 대신 페이지 맨 아래에서 코드를 실행하여 해당 문제를 쉽게 해결할 수 있습니다. HTML5Boilerplate 은이 정확한 접근법을 사용합니다.
Blazemonger 2016 년

3
DOMContentLoaded를 사용하지 않는 이유는 무엇입니까? IE9 + caniuse.com/domcontentloaded developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
Brock

문서 마지막에 전화를 걸어 문제를 해결했습니다. 함수가 호출되면 모든 것이로드됩니다.
IgniteCoders

답변:


1440

IE8이 아닌 98 % 이상의 브라우저 에서 DOMContentLoaded지원되는 표준 기반 대체 가 있습니다 .

document.addEventListener("DOMContentLoaded", function(event) { 
  //do work
});

jQuery의 기본 기능은 아래 그림과 같이 window.onload보다 훨씬 복잡합니다.

function bindReady(){
    if ( readyBound ) return;
    readyBound = true;

    // Mozilla, Opera and webkit nightlies currently support this event
    if ( document.addEventListener ) {
        // Use the handy event callback
        document.addEventListener( "DOMContentLoaded", function(){
            document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
            jQuery.ready();
        }, false );

    // If IE event model is used
    } else if ( document.attachEvent ) {
        // ensure firing before onload,
        // maybe late but safe also for iframes
        document.attachEvent("onreadystatechange", function(){
            if ( document.readyState === "complete" ) {
                document.detachEvent( "onreadystatechange", arguments.callee );
                jQuery.ready();
            }
        });

        // If IE and not an iframe
        // continually check to see if the document is ready
        if ( document.documentElement.doScroll && window == window.top ) (function(){
            if ( jQuery.isReady ) return;

            try {
                // If IE is used, use the trick by Diego Perini
                // http://javascript.nwbox.com/IEContentLoaded/
                document.documentElement.doScroll("left");
            } catch( error ) {
                setTimeout( arguments.callee, 0 );
                return;
            }

            // and execute any waiting functions
            jQuery.ready();
        })();
    }

    // A fallback to window.onload, that will always work
    jQuery.event.add( window, "load", jQuery.ready );
}

19
누군가가 코드를 원한다면 실제로 작동하는 일반 자바 스크립트 구현입니다. stackoverflow.com/questions/9899372/…
jfriend00

4
jQuery DOM 준비 코드가 단순화 된 것으로 보입니다 : github.com/jquery/jquery/blob/master/src/core/ready.js
Jose Nobile

2
@JoseNobile에게 그들은 오래된 브라우저 지원 감소하기 때문에
huysentruitw

16
우리는 모두 IE8에서 시작할 준비가 된 것 같습니다 ...;). 링크 @JoseNobile에 감사드립니다.
Con Antonakos

13
스크립트가 나중에로드되면 DOMContentLoaded가 작동하지 않습니다. JQuery 문서 준비가 항상 실행됩니다.
Jared Insel

343

편집하다:

다음은 jQuery를 대체 할 수있는 대안입니다.

function ready(callback){
    // in case the document is already rendered
    if (document.readyState!='loading') callback();
    // modern browsers
    else if (document.addEventListener) document.addEventListener('DOMContentLoaded', callback);
    // IE <= 8
    else document.attachEvent('onreadystatechange', function(){
        if (document.readyState=='complete') callback();
    });
}

ready(function(){
    // do something
});

https://plainjs.com/javascript/events/running-code-when-the-document-is-ready-15/ 에서 가져온

https://stackoverflow.com/a/9899701/175071 에서 가져온 또 다른 좋은 domReady 기능


허용 된 답변이 완전히 완료되지 jQuery.ready()않았으므로 jQuery 1.6.2 소스를 기반으로 하는 "준비"기능을 함께 연결했습니다 .

var ready = (function(){

    var readyList,
        DOMContentLoaded,
        class2type = {};
        class2type["[object Boolean]"] = "boolean";
        class2type["[object Number]"] = "number";
        class2type["[object String]"] = "string";
        class2type["[object Function]"] = "function";
        class2type["[object Array]"] = "array";
        class2type["[object Date]"] = "date";
        class2type["[object RegExp]"] = "regexp";
        class2type["[object Object]"] = "object";

    var ReadyObj = {
        // Is the DOM ready to be used? Set to true once it occurs.
        isReady: false,
        // A counter to track how many items to wait for before
        // the ready event fires. See #6781
        readyWait: 1,
        // Hold (or release) the ready event
        holdReady: function( hold ) {
            if ( hold ) {
                ReadyObj.readyWait++;
            } else {
                ReadyObj.ready( true );
            }
        },
        // Handle when the DOM is ready
        ready: function( wait ) {
            // Either a released hold or an DOMready/load event and not yet ready
            if ( (wait === true && !--ReadyObj.readyWait) || (wait !== true && !ReadyObj.isReady) ) {
                // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
                if ( !document.body ) {
                    return setTimeout( ReadyObj.ready, 1 );
                }

                // Remember that the DOM is ready
                ReadyObj.isReady = true;
                // If a normal DOM Ready event fired, decrement, and wait if need be
                if ( wait !== true && --ReadyObj.readyWait > 0 ) {
                    return;
                }
                // If there are functions bound, to execute
                readyList.resolveWith( document, [ ReadyObj ] );

                // Trigger any bound ready events
                //if ( ReadyObj.fn.trigger ) {
                //    ReadyObj( document ).trigger( "ready" ).unbind( "ready" );
                //}
            }
        },
        bindReady: function() {
            if ( readyList ) {
                return;
            }
            readyList = ReadyObj._Deferred();

            // Catch cases where $(document).ready() is called after the
            // browser event has already occurred.
            if ( document.readyState === "complete" ) {
                // Handle it asynchronously to allow scripts the opportunity to delay ready
                return setTimeout( ReadyObj.ready, 1 );
            }

            // Mozilla, Opera and webkit nightlies currently support this event
            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", ReadyObj.ready, false );

            // If IE event model is used
            } else if ( document.attachEvent ) {
                // 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", ReadyObj.ready );

                // If IE and not a frame
                // continually check to see if the document is ready
                var toplevel = false;

                try {
                    toplevel = window.frameElement == null;
                } catch(e) {}

                if ( document.documentElement.doScroll && toplevel ) {
                    doScrollCheck();
                }
            }
        },
        _Deferred: function() {
            var // callbacks list
                callbacks = [],
                // stored [ context , args ]
                fired,
                // to avoid firing when already doing so
                firing,
                // flag to know if the deferred has been cancelled
                cancelled,
                // the deferred itself
                deferred  = {

                    // done( f1, f2, ...)
                    done: function() {
                        if ( !cancelled ) {
                            var args = arguments,
                                i,
                                length,
                                elem,
                                type,
                                _fired;
                            if ( fired ) {
                                _fired = fired;
                                fired = 0;
                            }
                            for ( i = 0, length = args.length; i < length; i++ ) {
                                elem = args[ i ];
                                type = ReadyObj.type( elem );
                                if ( type === "array" ) {
                                    deferred.done.apply( deferred, elem );
                                } else if ( type === "function" ) {
                                    callbacks.push( elem );
                                }
                            }
                            if ( _fired ) {
                                deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
                            }
                        }
                        return this;
                    },

                    // resolve with given context and args
                    resolveWith: function( context, args ) {
                        if ( !cancelled && !fired && !firing ) {
                            // make sure args are available (#8421)
                            args = args || [];
                            firing = 1;
                            try {
                                while( callbacks[ 0 ] ) {
                                    callbacks.shift().apply( context, args );//shifts a callback, and applies it to document
                                }
                            }
                            finally {
                                fired = [ context, args ];
                                firing = 0;
                            }
                        }
                        return this;
                    },

                    // resolve with this as context and given arguments
                    resolve: function() {
                        deferred.resolveWith( this, arguments );
                        return this;
                    },

                    // Has this deferred been resolved?
                    isResolved: function() {
                        return !!( firing || fired );
                    },

                    // Cancel
                    cancel: function() {
                        cancelled = 1;
                        callbacks = [];
                        return this;
                    }
                };

            return deferred;
        },
        type: function( obj ) {
            return obj == null ?
                String( obj ) :
                class2type[ Object.prototype.toString.call(obj) ] || "object";
        }
    }
    // The DOM ready check for Internet Explorer
    function doScrollCheck() {
        if ( ReadyObj.isReady ) {
            return;
        }

        try {
            // If IE is used, use the trick by Diego Perini
            // http://javascript.nwbox.com/IEContentLoaded/
            document.documentElement.doScroll("left");
        } catch(e) {
            setTimeout( doScrollCheck, 1 );
            return;
        }

        // and execute any waiting functions
        ReadyObj.ready();
    }
    // Cleanup functions for the document ready method
    if ( document.addEventListener ) {
        DOMContentLoaded = function() {
            document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
            ReadyObj.ready();
        };

    } else if ( document.attachEvent ) {
        DOMContentLoaded = function() {
            // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
            if ( document.readyState === "complete" ) {
                document.detachEvent( "onreadystatechange", DOMContentLoaded );
                ReadyObj.ready();
            }
        };
    }
    function ready( fn ) {
        // Attach the listeners
        ReadyObj.bindReady();

        var type = ReadyObj.type( fn );

        // Add the callback
        readyList.done( fn );//readyList is result of _Deferred()
    }
    return ready;
})();

사용하는 방법:

<script>
    ready(function(){
        alert('It works!');
    });
    ready(function(){
        alert('Also works!');
    });
</script>

이 코드의 기능이 확실하지 않지만 표면 테스트에서 제대로 작동했습니다. 시간이 오래 걸리기 때문에 여러분과 다른 사람들이 혜택을 누릴 수 있기를 바랍니다.

추신 : 나는 그것을 컴파일 하는 것이 좋습니다 .

또는 http://dustindiaz.com/smallest-domready-ever 를 사용할 수 있습니다 :

function r(f){/in/.test(document.readyState)?setTimeout(r,9,f):f()}
r(function(){/*code to run*/});

또는 새 브라우저 만 지원해야하는 경우 기본 기능 (jQuery 준비와 달리 페이지가로드 된 후 추가하면 실행되지 않음)

document.addEventListener('DOMContentLoaded',function(){/*fun code to run*/})

14
@TimoHuovinen 대안 : Zepto.js (9.1kb), Snack.js (8.1kb), $ dom (2.3kb) 및 140 Medley (0.5kb). 편집 : Ender를 살펴볼 수도 있습니다.
Frederik Krautwald

2
@FrederikKrautwald $ dom은 내가 원하는 것 같지만 청구서에 맞는지 확실하지 않습니다. Zepto도 정말 유망 해 보입니다. 공유해 주셔서 감사합니다!
Timo Huovinen


2
@ 티모 Huovinen : 귀하의 질문은 정말, 정말 광범위합니다! jQuery가 만들어 졌을 때 오늘날 덜 중요한 브라우저에서 생성 된 많은 크로스 브라우저 문제가 발생했습니다. 오늘날 "자바 스크립트 만"이 그 어느 때보 다 쉬워졌습니다. 현재 "큰 20kb 압축, 모두 포함"을 작성하는 것은 많은 이유에서 필자가 모두 나열하지 않는 것이 좋습니다.
dotpush

1
나는 이것을 좋아하지 않는다. 사람들 이이 답변을 선호한다면 왜 jQuery를 먼저 삭제 해야하는지 스스로에게 물어보십시오. 브라우저 폴백을 모두 번들로 다시 가져와 정확히 동일한 기능을 추출하려는 경우에는 의미가 없습니다. 처음부터 jQuery를 피하는 것이 중요하지 않습니까?
Phil

208

세 가지 옵션 :

  1. 경우 script몸의 마지막 태그는, DOM은 스크립트 태그가 실행 전에 준비가 될 것입니다
  2. DOM이 준비되면 "readyState"가 "complete"로 변경됩니다.
  3. 'DOMContentLoaded'이벤트 리스너 아래에 모든 것을 넣으십시오.

준비 상태 변경

  document.onreadystatechange = function () {
     if (document.readyState == "complete") {
     // document is ready. Do your stuff here
   }
 }

출처 : MDN

DOMContentLoaded

document.addEventListener('DOMContentLoaded', function() {
   console.log('document is ready. I can sleep now');
});

석기 시대의 브라우저에 관심이있는 경우 : jQuery 소스 코드로 이동하여ready함수를사용하십시오. 이 경우 전체 라이브러리를 파싱하거나 실행하지 않고 아주 작은 부분 만 수행합니다.


3
이 두 번째 예는 표시된 답변보다 훨씬 우아하고 간결합니다. 왜 이것이 올바른 것으로 표시되지 않았습니까?
0112

2
DOMContentLoaded 일에 대해서는 여전히 +1이며, 내가 원하는 것을 정확하게 수행했습니다.
tripleee

1
onreadystatechange가 나를 위해 속임수를 썼습니다 ... 비동기 jquery로드 후 일부 스크립트를 실행해야했습니다.
Abram

2
참고로, # 1은 전적으로 사실이 아닙니다. DOM이 완료되기 전에 페이지 끝에있는 스크립트가로드 될 수 있습니다. 리스너가 우월한 이유입니다. 브라우저가 완료되면 청취합니다. 마지막에 넣으면 스크립트로드가 브라우저가 렌더링 할 수있는 것보다 느리다는 것을 손가락으로 가리고 있습니다.
Machavity

1
이 변형은 문서가 이미로드 된 후에도 작동합니다. 가능한 경우 다음과 같이 (imo best) 답변을 업데이트하십시오. if (document.readyState == 'complete') {init (); } else {document.onreadystatechange = function () {if (document.readyState == 'complete') {init (); }}}
ZPiDER

87

닫는 태그 앞에<script>/*JavaScript code*/</script> 오른쪽 놓습니다 </body>.

분명히 이것은 JavaScript 파일 a la에서 무언가를하는 것이 아니라 HTML 파일을 변경해야하기 때문에 모든 사람의 목적에 적합 document.ready하지는 않지만 여전히 ...


페이지가 아직 준비되지 않았으므로 이러한 브라우저와 브라우저에서이 작업을 수행 할 수 없습니다. 호환성 문제가있는 것 같습니다. 불행히도 나는 더 명확하게 기억할 수 없다. 그럼에도 불구하고 모든 경우의 99 %에서 충분히 가까운 방법으로 +1하십시오 (Yahoo!에서 제안).
Boldewyn 2009

7
실제로, 페이지 하단에 스크립트 요소를 배치하는 것은 거의 완벽한 솔루션입니다. 크로스 브라우저로 작동하고 document.ready 완벽을 시뮬레이션합니다. 유일한 단점은 일부 스마트 코드를 사용하는 것보다 눈에 잘 띄지 않는다는 것입니다. 작성하는 스크립트 사용자에게 준비 또는 초기화 함수를 호출하기 위해 추가 스크립트 조각을 추가하도록 요청해야합니다.
Stijn de Witt

@StijndeWitt-init 함수를 호출해야한다는 것은 무엇을 의미합니까? document.ready를 사용하는 스크립트는이를 호출하기 위해 다른 클라이언트 코드가 필요하지 않으며 자체 포함되어 있으며 본문 끝에 코드가 포함되어있는 것과 동일하며 자체 포함되어 있지 않습니다. 다른 코드를 호출해야합니다.
nnnnnn

1
닫는 본문 태그 뒤에 그리고 닫는 태그 앞에 스크립트를 넣지 </html>않겠습니까?
Charles Holbrow

1
@CharlesHolbrow 모든 브라우저에서 올바르게 해석하지만 유효한 html이 되려면 html태그에 head및 만 포함되어야합니다 body.
Alvaro Montoro

66

불쌍한 사람의 해결책 :

var checkLoad = function() {   
    document.readyState !== "complete" ? setTimeout(checkLoad, 11) : alert("loaded!");   
};  

checkLoad();  

바이올린보기

이 것, 조금 더 나은, 자신의 범위 및 비 재귀를 추가

(function(){
    var tId = setInterval(function() {
        if (document.readyState == "complete") onComplete()
    }, 11);
    function onComplete(){
        clearInterval(tId);    
        alert("loaded!");    
    };
})()

바이올린보기


8
@PhilipLangford 아니면 그냥 안에 넣고 setInterval재귀를 완전히 제거하십시오.
Alex W

1
@ Raveren, 흠 당신이 맞아요, 게시 할 때 테스트했다고 확신합니다. 어쨌든, 그것은 훨씬 더 단순 해졌으며 이제는 함수가 래핑되지 않고 방금 호출되었습니다.
Jakob Sternberg

24
이 섹시하지 않습니다. 아뇨 타이머 / 간격을 사용하여 물건을 감지하면 "작동"할 수 있지만 이와 같은 프로그래밍을 계속하면 더 큰 프로젝트가 염려됩니다. 이런 식으로 물건을 해킹하지 마십시오. 제대로 해 부디. 이러한 종류의 코드는 더 나은 솔루션이 있고이를 알고 있기 때문에 개발 생태계에 해를 끼칩니다.
dudewad

1
나는이 답변이 dustindiaz.com/smallest-domready-ever와 훨씬 더 가깝다고 생각합니다. 그래서 나는 스크립트를 개선했습니다 : jsfiddle.net/iegik/PT7x9
iegik

1
@ReidBlomquist 그렇습니다. 이것은 "잘못된"방법이며, 제가 지적하고있는 것입니다 (조금 나쁘지만 알고 있습니다). 당신은 그것을 잘못함으로써 생태계를 어떻게 든 "도움"한다고 말할 수 있지만, 문제는 나쁜 코드의 양이 많을수록 사람들이 더 잘 알 경험이 없기 때문에 "좋은"코드를 취하는 것입니다 그들이 나쁜 코드를 가져 와서 실제 프로덕션 아키텍처 솔루션으로 구현할 것이기 때문에 생태계에 도움이되지 않습니다. 따라서이 "오류"에 대한 의견이 달라져야 할 것 같습니다.
dudewad

34

나는 이것을 사용한다 :

document.addEventListener("DOMContentLoaded", function(event) { 
    //Do work
});

참고 : 이것은 아마도 최신 브라우저에서만 작동하며, 특히 다음과 같습니다. http://caniuse.com/#feat=domcontentloaded


13
IE9 이상 실제로
Pascalius

document_start 또는 document_idle 이벤트를 연결하는 경우 Chrome 확장 프로그램 콘텐츠 스크립트에서도 효과적입니다.
Volomike

21

실제로 Internet Explorer 9 이상 에만 관심이 있다면 이 코드만으로도 충분합니다 jQuery.ready.

    document.addEventListener("DOMContentLoaded", callback);

Internet Explorer 6 과 정말 이상하고 드문 브라우저 에 대해 걱정한다면 다음 과 같이 작동합니다.

domReady: function (callback) {
    // Mozilla, Opera and WebKit
    if (document.addEventListener) {
        document.addEventListener("DOMContentLoaded", callback, false);
        // If Internet Explorer, the event model is used
    } else if (document.attachEvent) {
        document.attachEvent("onreadystatechange", function() {
            if (document.readyState === "complete" ) {
                callback();
            }
        });
        // A fallback to window.onload, that will always work
    } else {
        var oldOnload = window.onload;
        window.onload = function () {
            oldOnload && oldOnload();
            callback();
        }
    }
},

18

이 질문은 아주 오래 전에 요청되었습니다. 이 질문을 보는 사람이라면 누구나 "jquery가 필요하지 않을 수도 있습니다" 라는 사이트가 있습니다.이 사이트는 필요한 IE 지원 수준에 따라 jquery의 모든 기능을 분해하고 일부 대안적인 작은 라이브러리를 제공합니다.

jquery가 필요하지 않을 수도있는 IE8 문서 준비 스크립트

function ready(fn) {
    if (document.readyState != 'loading')
        fn();
    else if (document.addEventListener)
        document.addEventListener('DOMContentLoaded', fn);
    else
        document.attachEvent('onreadystatechange', function() {
            if (document.readyState != 'loading')
                fn();
        });
}

나는 왜 궁금 'onreadystatechange'보다는 필요하다document.attachEvent('onload', fn);
누가 복음

13

최근에 이것을 모바일 사이트에 사용하고있었습니다. 이것은 "Pro JavaScript Techniques"의 John Resig의 단순화 된 버전입니다. addEvent에 따라 다릅니다.

var ready = ( function () {
  function ready( f ) {
    if( ready.done ) return f();

    if( ready.timer ) {
      ready.ready.push(f);
    } else {
      addEvent( window, "load", isDOMReady );
      ready.ready = [ f ];
      ready.timer = setInterval(isDOMReady, 13);
    }
  };

  function isDOMReady() {
    if( ready.done ) return false;

    if( document && document.getElementsByTagName && document.getElementById && document.body ) {
      clearInterval( ready.timer );
      ready.timer = null;
      for( var i = 0; i < ready.ready.length; i++ ) {
        ready.ready[i]();
      }
      ready.ready = null;
      ready.done = true;
    }
  }

  return ready;
})();

13
이 코드에주의하십시오. $ (document) .ready와 동일하지 않습니다. 이 코드는 document.body가 준비되면 콜백을 트리거하여 DOM이 완전히로드되었음을 보장하지 않습니다.
Karolis

12

크로스 브라우저 (이전 브라우저도 해당) 및 간단한 솔루션 :

var docLoaded = setInterval(function () {
    if(document.readyState !== "complete") return;
    clearInterval(docLoaded);

    /*
        Your code goes here i.e. init()
    */
}, 30);

jsfiddle에 경고 표시


DOM을로드하는 데 30ms 이상 걸리는 경우를 제외하고는 코드가 실행되지 않습니다.
Quelklef

1
@Quelklef thats setInterval not setTimeout
Pawel

11

jQuery 답변은 나에게 매우 유용했습니다. 약간의 재가공으로 그것은 나의 요구를 잘 충족 시켰습니다. 다른 사람에게 도움이되기를 바랍니다.

function onReady ( callback ){
    var addListener = document.addEventListener || document.attachEvent,
        removeListener =  document.removeEventListener || document.detachEvent
        eventName = document.addEventListener ? "DOMContentLoaded" : "onreadystatechange"

    addListener.call(document, eventName, function(){
        removeListener( eventName, arguments.callee, false )
        callback()
    }, false )
}

일부 브라우저에서는 removeListener컨텍스트를 문서와 함께 호출해야합니다. removeListener.call(document, ...
Ron

9

다음은 모든 브라우저에서 작동하는 DOM 준비를 테스트 하는 가장 작은 코드 스 니펫입니다 (IE 8조차도).

r(function(){
    alert('DOM Ready!');
});
function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}

답변을 참조하십시오 .


6

HTML 페이지 하단에 추가하면됩니다.

<script>
    Your_Function();
</script>

HTML 문서는 맨 아래에서 구문 분석되기 때문입니다.


7
이 코드가 실행될 때 DOM이 빌드되었음을 어떻게 알 수 있습니까? 로드되고 파싱 된 CSS를 포함합니까? 브라우저 API DOMContentLoaded는이를 위해 설계되었습니다.
Dan

실제로 js와 관련하여 수행하려는 작업에 따라 다릅니다. 페이지가 끝났을 때 실제로 무언가를 실행 해야하는 경우.
davefrassoni 1

5

Rock Solid addEvent ()http://www.braksator.com/how-to-make-your-own-jquery 에서 볼 가치가 있습니다.

사이트가 다운되는 경우의 코드는 다음과 같습니다.

function addEvent(obj, type, fn) {
    if (obj.addEventListener) {
        obj.addEventListener(type, fn, false);
        EventCache.add(obj, type, fn);
    }
    else if (obj.attachEvent) {
        obj["e"+type+fn] = fn;
        obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
        obj.attachEvent( "on"+type, obj[type+fn] );
        EventCache.add(obj, type, fn);
    }
    else {
        obj["on"+type] = obj["e"+type+fn];
    }
}

var EventCache = function(){
    var listEvents = [];
    return {
        listEvents : listEvents,
        add : function(node, sEventName, fHandler){
            listEvents.push(arguments);
        },
        flush : function(){
            var i, item;
            for(i = listEvents.length - 1; i >= 0; i = i - 1){
                item = listEvents[i];
                if(item[0].removeEventListener){
                    item[0].removeEventListener(item[1], item[2], item[3]);
                };
                if(item[1].substring(0, 2) != "on"){
                    item[1] = "on" + item[1];
                };
                if(item[0].detachEvent){
                    item[0].detachEvent(item[1], item[2]);
                };
                item[0][item[1]] = null;
            };
        }
    };
}();

// Usage
addEvent(window, 'unload', EventCache.flush);
addEvent(window, 'load', function(){alert("I'm ready");});

두 번째 링크가 끊어졌습니다.
Peter Mortensen


4

이 크로스 브라우저 코드는 DOM이 준비되면 함수를 호출합니다.

var domReady=function(func){
    var scriptText='('+func+')();';
    var scriptElement=document.createElement('script');
    scriptElement.innerText=scriptText;
    document.body.appendChild(scriptElement);
};

작동 방식은 다음과 같습니다.

  1. 의 첫 번째 줄 domReady통화량toString 함수 메서드 전달한 함수의 문자열 표현을 가져 와서 즉시 함수를 호출하는 표현식으로 래핑합니다.
  2. 나머지는 domReady표현식 을 사용하여 스크립트 요소 를 작성하고body 하여 문서의 .
  3. 브라우저는 bodyDOM이 준비된 후에 추가 된 스크립트 태그를 실행합니다 .

예를 들어,이 작업을 수행 domReady(function(){alert();});하면 body요소에 다음이 추가됩니다 .

 <script>(function (){alert();})();</script>

이것은 사용자 정의 함수에서만 작동합니다. 다음은 작동하지 않습니다.domReady(alert);


3

이 솔루션은 어떻습니까?

// other onload attached earlier
window.onload=function() {
   alert('test');
};

tmpPreviousFunction=window.onload ? window.onload : null;

// our onload function
window.onload=function() {
   alert('another message');

   // execute previous one
   if (tmpPreviousFunction) tmpPreviousFunction();
};

3
"load"가있는 창에서 addEventListener를 사용할 수 있습니다. 리스너는 하나씩 실행되며 수동 연결이 필요하지 않습니다.
Zaffy

1
그러나로드는 준비와 다릅니다. '로드'는 문서가 '준비'되기 전에 발생합니다. 준비된 문서에 DOM이로드되어 있고로드 된 창에 반드시 DOM이 준비되어 있지는 않습니다. 좋은 답변
Mzn

1
@ Mzn : 거꾸로 생각합니다. 창로드 이벤트 전에 문서 준비가 완료된 것 같습니다 . "일반적으로 모든 이미지가 완전히로드 될 때까지 기다릴 필요는 없습니다. 코드를 더 일찍 실행할 수있는 경우 일반적으로 .ready () 메서드로 전송 된 핸들러에 배치하는 것이 가장 좋습니다." ( api.jquery.com/load-event )
Tyler Rick

이것은 페이지의 나머지 window.onload 이벤트를 무시하고 문제를 일으킬 것입니다. 기존 이벤트 위에 이벤트를 추가해야합니다.
Teoman shipahi

로드 이벤트가 너무 늦을 수 있습니다. 타사 외부 js / 이미지에 따라 사용하는 것이 고통 스럽습니다 ... 제어 할 수없는 응답이없는 서버로 모든 것이 실패합니다. DOMContentLoaded를 사용하는 것은 최적화 일뿐만 아니라 더 안전합니다!
dotpush December

3

jQuery와 비교할 때 항상 JavaScript와 동등한 것을 사용하는 것이 좋습니다. 하나의 이유는 의존 할 라이브러리가 적기 때문에 jQuery와 동등한 것보다 훨씬 빠릅니다.

jQuery 등가물에 대한 환상적인 참고 자료는 http://youmightnotneedjquery.com/ 입니다.

귀하의 질문에 관한 한, 위의 링크에서 아래 코드를 가져 왔습니다. :)주의 사항은 Internet Explorer 9 이상 에서만 작동한다는 것입니다 .

function ready(fn) {
    if (document.readyState != 'loading') {
        fn();
    }
    else {
        document.addEventListener('DOMContentLoaded', fn);
    }
}

3

최소 및 100 % 작업

PlainJS 에서 답변을 선택했으며 제대로 작동합니다. DOMContentLoaded모든 브라우저에서 사용할 수 있도록 확장됩니다 .


이 함수는 jQuery의 $(document).ready()메소드 와 동일합니다 .

document.addEventListener('DOMContentLoaded', function(){
    // do something
});

그러나 jQuery와 달리이 코드는 최신 브라우저 (IE> 8)에서만 제대로 실행되며이 스크립트가 삽입 될 때 (예 : Ajax를 통해) 문서가 이미 렌더링 된 경우에는 적용되지 않습니다. 따라서이 부분을 조금 확장해야합니다.

function run() {
    // do something
}

// in case the document is already rendered
if (document.readyState!='loading') run();
// modern browsers
else if (document.addEventListener) 
document.addEventListener('DOMContentLoaded', run);
// IE <= 8
else document.attachEvent('onreadystatechange', function(){
    if (document.readyState=='complete') run();
});

이것은 기본적으로 모든 가능성을 다루며 jQuery 도우미를 대체 할 수 있습니다.



2

우리는 최소한의 구현으로 가장 간단한 경우에 대한 트릭을 수행 할 수있는 빠르고 더러운 크로스 브라우저 구현을 발견했습니다.

window.onReady = function onReady(fn){
    document.body ? fn() : setTimeout(function(){ onReady(fn);},50);
};

무엇 doc.body입니까!?
Nabi KAZ

2

여기에 제시된 setTimeout / setInterval 솔루션은 특정 상황에서만 작동합니다.

이 문제는 특히 이전 Internet Explorer 버전 8 이하에서 나타납니다.

이러한 setTimeout / setInterval 솔루션의 성공에 영향을주는 변수는 다음과 같습니다.

1) dynamic or static HTML
2) cached or non cached requests
3) size of the complete HTML document
4) chunked or non chunked transfer encoding

이 특정 문제를 해결하는 원래 (기본 Javascript) 코드는 다음과 같습니다.

https://github.com/dperini/ContentLoaded
http://javascript.nwbox.com/ContentLoaded (test)

이것은 jQuery 팀이 구현 한 코드입니다.


1

여기 제가 사용하는 것이 있습니다. 빠르고 빠르며 제가 생각하는 모든 기초를 다룹니다. IE <9를 제외한 모든 작업에 적용됩니다.

(() => { function fn() {
    // "On document ready" commands:
    console.log(document.readyState);
};  
  if (document.readyState != 'loading') {fn()}
  else {document.addEventListener('DOMContentLoaded', fn)}
})();

이것은 모든 경우를 잡는 것처럼 보입니다.

  • DOM이 이미 준비된 경우 즉시 실행됩니다 (DOM이 "로드 중"이 아니라 "대화식"또는 "완료"인 경우)
  • DOM이 여전히로드중인 경우 DOM을 사용할 수있는 경우 (대화식)에 대한 이벤트 리스너를 설정합니다.

DOMContentLoaded 이벤트는 IE9 및 기타 모든 항목에서 사용할 수 있으므로 개인적으로 사용하는 것이 좋습니다. ES2015에서 ES5로 코드를 변환하지 않으면 화살표 함수 선언을 일반 익명 함수로 다시 작성하십시오.

모든 자산이로드 될 때까지 기다리려면 모든 이미지가 표시되는 대신 window.onload를 대신 사용하십시오.


1

아주 오래된 브라우저를 지원할 필요가없는 경우, 외부 스크립트가 async 속성으로 로드 된 경우에도이를 수행하는 방법은 다음과 같습니다.

HTMLDocument.prototype.ready = new Promise(function(resolve) {
   if(document.readyState != "loading")
      resolve();
   else
      document.addEventListener("DOMContentLoaded", function() {
         resolve();
      });
});

document.ready.then(function() {
   console.log("document.ready");
});

0

IE9 +의 경우 :

function ready(fn) {
  if (document.readyState != 'loading'){
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}

0

BODY 하단 근처에 jQuery를로드하고 있지만 jQuery (<func>) 또는 jQuery (document) .ready (<func>)를 작성하는 코드에 문제가 있는 경우 Github 에서 jqShim 을 확인하십시오 .

자체 문서 준비 기능을 다시 만드는 대신 jQuery를 사용할 수있을 때까지 함수를 유지 한 다음 예상대로 jQuery를 진행합니다. jQuery를 본문의 맨 아래로 이동하는 요점은 페이지로드 속도를 높이는 것입니다. 템플릿 헤드에 jqShim.min.js를 인라인하여이를 수행 할 수 있습니다.

나는 WordPress의 모든 스크립트를 바닥 글로 옮기기 위해이 코드를 작성 했으며이 shim 코드는 이제 헤더에 직접 자리 잡고 있습니다.


0

이 시도:

function ready(callback){
    if(typeof callback === "function"){
        document.addEventListener("DOMContentLoaded", callback);
        window.addEventListener("load", callback);
    }else{
        throw new Error("Sorry, I can not run this!");
    }
}
ready(function(){
    console.log("It worked!");
});

당신은 콜백을 두 번 실행할 것입니다
앤드류

0
function onDocReady(fn){ 
    $d.readyState!=="loading" ? fn():document.addEventListener('DOMContentLoaded',fn);
}

function onWinLoad(fn){
    $d.readyState==="complete") ? fn(): window.addEventListener('load',fn);
} 

onDocReady 는 HTML DOM이 완전히 액세스 / 파싱 / 조작 할 준비가되면 콜백을 제공합니다.

onWinLoad 는 모든 것이로드 될 때 콜백을 제공합니다 (이미지 등)

  • 이 함수들은 원할 때마다 호출 할 수 있습니다.
  • 여러 "리스너"를 지원합니다.
  • 모든 브라우저에서 작동합니다.

0
(function(f){
  if(document.readyState != "loading") f();
  else document.addEventListener("DOMContentLoaded", f);
})(function(){
  console.log("The Document is ready");
});

이것은 다른 답변이하지 않는 것을 추가합니까?
dwjohnston

자체 폐쇄를 사용하며 (전역 "창"범위를 채우지 않음) 모든 브라우저에서 작동하며 매우 컴팩트합니다. 나는 다른 대답을 보지 못합니다.
더스틴 포 아상

jQuery.ready와 같이 DOM이 이미로드 된 후에도 작동하지만 대부분의 답변은 실패합니다.
더스틴 포 아상

0

대부분의 vanilla JS Ready 함수는 문서가 이미로드 된 DOMContentLoaded 핸들러가 설정된 시나리오를 고려하지 않습니다. 즉, 함수가 절대 실행되지 않습니다 . 외부 스크립트 ( ) 내에서 찾는 경우에 발생할 수 있습니다 .DOMContentLoadedasync<script async src="file.js"></script>

아래 코드 DOMContentLoaded는 문서 readyState가 아직 interactive또는 이 아닌 경우에만 확인합니다 complete.

var DOMReady = function(callback) {
  document.readyState === "interactive" || document.readyState === "complete" ? callback() : document.addEventListener("DOMContentLoaded", callback());
};
DOMReady(function() {
  //DOM ready!
});

IE도 지원하려면 다음을 수행하십시오.

var DOMReady = function(callback) {
    if (document.readyState === "interactive" || document.readyState === "complete") {
        callback();
    } else if (document.addEventListener) {
        document.addEventListener('DOMContentLoaded', callback());
    } else if (document.attachEvent) {
        document.attachEvent('onreadystatechange', function() {
            if (document.readyState != 'loading') {
                callback();
            }
        });
    }
};

DOMReady(function() {
  // DOM ready!
});

0

나는 단순히 다음을 사용한다.

setTimeout(function(){
    //reference/manipulate DOM here
});

달리 그리고 document.addEventListener("DOMContentLoaded" //etc맨 대답, 그것은 멀리 다시 IE9 등으로 작동 - http://caniuse.com/#search=DOMContentLoaded는 전용으로 최근 IE11로 나타냅니다.

흥미롭게도 setTimeout2009 년 에이 솔루션을 우연히 발견 했습니다. DOM 과잉 준비 상태를 점검하고 있습니까? "DOM의 준비 상태를 확인하기 위해 다양한 프레임 워크의 더 복잡한 접근 방식을 사용하는 것이 과잉 상태"라는 의미로 약간 더 나은 표현이 될 수 있습니다.

이 기술이 작동하는 이유에 대한 나의 가장 좋은 설명은 그러한 setTimeout을 가진 스크립트에 도달했을 때 DOM이 구문 분석되는 중이므로 setTimeout 내의 코드 실행이 해당 작업이 완료 될 때까지 연기된다는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.