etc./StackOverFlow

jQuery의 $.ready()에 해당하는 순수 JavaScript - 페이지/DOM이 준비되었을 때 함수를 호출하는 방법 [중복]

청렴결백한 만능 재주꾼 2022. 1. 23. 13:36
반응형

질문자 :chris


jQuery를 사용하면 우리 모두는 멋진 .ready() 함수를 알고 있습니다.

 $('document').ready(function(){});

그러나 표준 JavaScript로 작성된 함수를 지원하는 라이브러리 없이 실행하고 페이지가 처리할 준비가 되는 즉시 함수를 시작하고 싶다고 가정해 보겠습니다. 이에 대한 적절한 접근 방법은 무엇입니까?

나는 내가 할 수 있다는 것을 안다:

 window.onload="myFunction()";

body 태그를 사용할 수 있습니다.

 <body onload="myFunction()">

또는 모든 작업을 마친 후 페이지 맨 아래에서 시도할 수도 있지만 다음 body 또는 html 태그는 다음과 같습니다.

 <script type="text/javascript"> myFunction(); </script>

$.ready() 와 같은 방식으로 하나 이상의 기능을 실행하는 브라우저 간(이전/신규) 호환 방법은 무엇입니까?



브라우저 간 호환성을 모두 수행하는 프레임워크가 없을 때 가장 간단한 방법은 본문 끝에 있는 코드를 호출하는 것입니다. 이것은 모든 이미지가 로드되는 것이 아니라 DOM이 준비될 때까지 기다리기 때문에 onload 핸들러보다 실행 속도가 더 빠릅니다. 그리고 이것은 모든 브라우저에서 작동합니다.

 <!doctype html> <html> <head> </head> <body> Your HTML here <script> // self executing function here (function() { // your page initialization code here // the DOM will be available here })(); </script> </body> </html>

최신 브라우저(IE9 이상 및 Chrome, Firefox 또는 Safari의 모든 버전)의 경우 $(document).ready() 메서드와 같은 jQuery를 구현하여 어디서나 호출할 수 있고 호출 스크립트가 있는 위치)에서 다음과 같이 사용할 수 있습니다.

 function docReady(fn) { // see if DOM is already available if (document.readyState === "complete" || document.readyState === "interactive") { // call on next available tick setTimeout(fn, 1); } else { document.addEventListener("DOMContentLoaded", fn); } }

용법:

 docReady(function() { // DOM is loaded and ready for manipulation here });

완전한 크로스 브라우저 호환성(이전 버전의 IE 포함)이 필요하고 window.onload $(document).ready() 메서드를 구현하는 방법을 살펴봐야 합니다. . 브라우저의 기능에 따라 상당히 관련이 있습니다.

jQuery가 하는 일(스크립트 태그가 배치되는 모든 위치에서 작동함)에 대한 약간의 아이디어를 제공합니다.

지원되는 경우 표준을 시도합니다.

 document.addEventListener('DOMContentLoaded', fn, false);

대체:

 window.addEventListener('load', fn, false )

또는 이전 버전의 IE에서는 다음을 사용합니다.

 document.attachEvent("onreadystatechange", fn);

대체:

 window.attachEvent("onload", fn);

그리고 IE 코드 경로에는 내가 따르지 않는 몇 가지 해결 방법이 있지만 프레임과 관련이 있는 것 같습니다.


다음은 일반 자바스크립트로 작성된 .ready() 를 완전히 대체한 것입니다.

 (function(funcName, baseObj) { // The public function name defaults to window.docReady // but you can pass in your own object and own function name and those will be used // if you want to put them in a different namespace funcName = funcName || "docReady"; baseObj = baseObj || window; var readyList = []; var readyFired = false; var readyEventHandlersInstalled = false; // call this when the document is ready // this function protects itself against being called more than once function ready() { if (!readyFired) { // this must be set to true before we start calling callbacks readyFired = true; for (var i = 0; i < readyList.length; i++) { // if a callback here happens to add new ready handlers, // the docReady() function will see that it already fired // and will schedule the callback to run right after // this event loop finishes so all handlers will still execute // in order and no new ones will be added to the readyList // while we are processing the list readyList[i].fn.call(window, readyList[i].ctx); } // allow any closures held by these functions to free readyList = []; } } function readyStateChange() { if ( document.readyState === "complete" ) { ready(); } } // This is the one public interface // docReady(fn, context); // the context argument is optional - if present, it will be passed // as an argument to the callback baseObj[funcName] = function(callback, context) { if (typeof callback !== "function") { throw new TypeError("callback for docReady(fn) must be a function"); } // if ready has already fired, then just schedule the callback // to fire asynchronously, but right away if (readyFired) { setTimeout(function() {callback(context);}, 1); return; } else { // add the function and context to the list readyList.push({fn: callback, ctx: context}); } // if document already ready to go, schedule the ready function to run if (document.readyState === "complete") { setTimeout(ready, 1); } else if (!readyEventHandlersInstalled) { // otherwise if we don't have event handlers installed, install them if (document.addEventListener) { // first choice is DOMContentLoaded event document.addEventListener("DOMContentLoaded", ready, false); // backup is window load event window.addEventListener("load", ready, false); } else { // must be IE document.attachEvent("onreadystatechange", readyStateChange); window.attachEvent("onload", ready); } readyEventHandlersInstalled = true; } } })("docReady", window);

최신 버전의 코드는 https://github.com/jfriend00/docReady의 GitHub에서 공개적으로 공유됩니다.

용법:

 // pass a function reference docReady(fn); // use an anonymous function docReady(function() { // code here }); // pass a function reference and a context // the context will be passed to the function as the first argument docReady(fn, context); // use an anonymous function with a context docReady(function(context) { // code here that can use the context argument that was passed to docReady }, ctx);

이것은 다음에서 테스트되었습니다.

 IE6 and up Firefox 3.6 and up Chrome 14 and up Safari 5.1 and up Opera 11.6 and up Multiple iOS devices Multiple Android devices

작업 구현 및 테스트 베드: http://jsfiddle.net/jfriend00/YfD3C/


작동 방식을 요약하면 다음과 같습니다.

  1. 공개되지 않은 상태 변수를 가질 수 있도록 IIFE (즉시 호출된 함수 표현식)를 만듭니다.
  2. 공개 함수 docReady(fn, context)
  3. docReady(fn, context) 가 호출되면 ready 핸들러가 이미 실행되었는지 확인하십시오. setTimeout(fn, 1) 끝난 직후 새로 추가된 콜백이 실행되도록 예약하십시오.
  4. 준비 처리기가 아직 실행되지 않은 경우 이 새 콜백을 나중에 호출할 콜백 목록에 추가합니다.
  5. 문서가 이미 준비되었는지 확인하십시오. 그렇다면 모든 준비된 핸들러를 실행하십시오.
  6. 문서가 언제 준비되는지 알기 위해 아직 이벤트 리스너를 설치하지 않았다면 지금 설치하십시오.
  7. document.addEventListener 가 있는 경우 "DOMContentLoaded""load" 이벤트 모두에 대해 .addEventListener() 를 사용하여 이벤트 핸들러를 설치합니다. "로드"는 안전을 위한 백업 이벤트이며 필요하지 않아야 합니다.
  8. document.addEventListener "onreadystatechange""onload" 이벤트에 대해 .attachEvent() 를 사용하여 이벤트 핸들러를 설치합니다.
  9. onreadystatechange 이벤트에서 document.readyState === "complete" 인지 확인하고, 그렇다면 모든 준비 처리기를 실행하는 함수를 호출합니다.
  10. 다른 모든 이벤트 처리기에서 모든 준비 처리기를 실행하는 함수를 호출합니다.
  11. 모든 준비 처리기를 호출하는 함수에서 상태 변수를 확인하여 이미 실행되었는지 확인합니다. 있으면 아무 것도 하지 마십시오. 아직 호출되지 않았다면 준비된 함수의 배열을 반복하고 추가된 순서대로 각 함수를 호출합니다. 모두 호출되었음을 나타내는 플래그를 설정하여 두 번 이상 실행되지 않도록 합니다.
  12. 사용 중인 모든 클로저를 해제할 수 있도록 함수 배열을 지우십시오.

docReady() 로 등록된 핸들러는 등록된 순서대로 실행되도록 보장됩니다.

docReady(fn) 를 호출 setTimeout(fn, 1) 사용하여 현재 실행 스레드가 완료되는 즉시 콜백이 실행되도록 예약됩니다. 이것은 JS의 현재 스레드가 종료되고 호출 순서를 유지하는 즉시 이후가 되더라도 호출 코드가 항상 나중에 호출될 비동기 콜백이라고 가정할 수 있도록 합니다.


jfriend00

jQuery 없이 VANILLA 일반 JavaScript 를 수행하는 경우 다음을 사용해야 합니다(Internet Explorer 9 이상).

 document.addEventListener("DOMContentLoaded", function(event) { // Your code to run since DOM is loaded and ready });

위는 jQuery .ready 와 동일합니다.

 $(document).ready(function() { console.log("Ready!"); });

이와 같이 짧게 작성할 수도 있습니다. jQuery는 준비가 완료된 후에도 실행 됩니다 .

 $(function() { console.log("ready!"); });

BELOW와 혼동하지 마십시오 (DOM 준비를 의미하지 않음):

다음과 같이 자체 실행 되는 IIFE를 사용하지 마십시오.

 Example: (function() { // Your page initialization code here - WRONG // The DOM will be available here - WRONG })();

이 IIFE는 DOM이 로드될 때까지 기다리지 않습니다. (심지어 최신 버전의 Chrome 브라우저를 말하는 것입니다!)


Tom Stickel

모든 브라우저에서 작동 하는 순수한 자바스크립트 트릭과 함께 여기에서 가능한 몇 가지 방법을 언급하고 싶습니다.

 // with jQuery $(document).ready(function(){ /* ... */ }); // shorter jQuery version $(function(){ /* ... */ }); // without jQuery (doesn't work in older IEs) document.addEventListener('DOMContentLoaded', function(){ // your code goes here }, false); // and here's the trick (works everywhere) function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()} // use like r(function(){ alert('DOM Ready!'); });

여기서의 트릭은 원래 작성자가 설명했듯이 document.readyState 속성을 확인한다는 것입니다. 이 문자열이 포함 된 경우 in (같이 uninitializedloading , 처음 두 DOM 준비 상태를 5 점 만점) 우리는 시간 제한을 설정하고 다시 확인. 그렇지 않으면 전달된 함수를 실행합니다.

그리고 모든 브라우저에서 작동 하는 트릭에 대한 jsFiddle이 있습니다.

이를 책에 포함시킨 Tutorialzine 에 감사드립니다.


Ram Patra

IE9, 최신 Firefox 및 Chrome에서 테스트되었으며 IE8에서도 지원됩니다.

 document.onreadystatechange = function () { var state = document.readyState; if (state == 'interactive') { init(); } else if (state == 'complete') { initOnCompleteLoad(); } }​;

예: http://jsfiddle.net/electricvisions/Jackk/

업데이트 - 재사용 가능한 버전

방금 다음을 개발했습니다. 이전 버전과의 호환성 없이 준비된 jQuery 또는 Dom과 상당히 유사합니다. 아마도 추가 개선이 필요할 것입니다. 최신 버전의 Chrome, Firefox 및 IE(10/11)에서 테스트되었으며 댓글에 언급된 대로 이전 브라우저에서 작동해야 합니다. 문제가 발견되면 업데이트하겠습니다.

 window.readyHandlers = []; window.ready = function ready(handler) { window.readyHandlers.push(handler); handleState(); }; window.handleState = function handleState () { if (['interactive', 'complete'].indexOf(document.readyState) > -1) { while(window.readyHandlers.length > 0) { (window.readyHandlers.shift())(); } } }; document.onreadystatechange = window.handleState;

용법:

 ready(function () { // your code here });

JS의 비동기 로드를 처리하도록 작성되었지만 축소하지 않는 한 이 스크립트를 먼저 동기화 로드하는 것이 좋습니다. 개발에 유용하다는 것을 알았습니다.

최신 브라우저는 또한 경험을 더욱 향상시키는 비동기식 스크립트 로딩을 지원합니다. 비동기 지원은 페이지를 계속 렌더링하면서 동시에 여러 스크립트를 다운로드할 수 있음을 의미합니다. 비동기식으로 로드된 다른 스크립트에 의존하거나 축소기 또는 브라우저화와 같은 것을 사용하여 종속성을 처리할 때 주의하십시오.


Community Wiki

ready 포함하여 많은 jQuery 장점을 달성하기 위한 순수한 Javascript 방법론을 찾을 수 있는 리소스를 가지고 있습니다.

http://youmightnotneedjquery.com/#ready

 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(); }); } }

인라인 사용 예:

 ready(function() { alert('hello'); });

Lorcan O'Neill

나는 당신이 무엇을 요구하는지 잘 모르겠지만 아마도 이것이 도움이 될 수 있습니다.

 window.onload = function(){ // Code. . . }

또는:

 window.onload = main; function main(){ // Code. . . }

Zak The Hat

귀하의 방법(닫는 본문 태그 앞에 스크립트 배치)

 <script> myFunction() </script> </body> </html>

이전 및 새 브라우저를 지원하는 안정적인 방법입니다.


Kernel James

준비가 된

 function ready(fn){var d=document;(d.readyState=='loading')?d.addEventListener('DOMContentLoaded',fn):fn();}

다음과 같이 사용

 ready(function(){ //some code });

자체 호출 코드의 경우

 (function(fn){var d=document;(d.readyState=='loading')?d.addEventListener('DOMContentLoaded',fn):fn();})(function(){ //Some Code here //DOM is avaliable //var h1s = document.querySelector("h1"); });

지원: IE9+


Vitim.us

다음은 모든 브라우저에서 작동하는 Ram-swaroop의 "모든 브라우저에서 작동"을 평가하지 않고 정리한 버전입니다!

 function onReady(yourMethod) { var readyStateCheckInterval = setInterval(function() { if (document && document.readyState === 'complete') { // Or 'interactive' clearInterval(readyStateCheckInterval); yourMethod(); } }, 10); } // use like onReady(function() { alert('hello'); } );

그러나 실행하는 데 10ms가 추가로 기다리므로 다음과 같이 해서는 안 되는 더 복잡한 방법이 있습니다.

 function onReady(yourMethod) { if (document.readyState === 'complete') { // Or also compare to 'interactive' setTimeout(yourMethod, 1); // Schedule to run immediately } else { readyStateCheckInterval = setInterval(function() { if (document.readyState === 'complete') { // Or also compare to 'interactive' clearInterval(readyStateCheckInterval); yourMethod(); } }, 10); } } // Use like onReady(function() { alert('hello'); } ); // Or onReady(functionName);

프레임워크 없이 DOM이 준비되었는지 확인하는 방법 도 참조하세요. .


rogerdpack

document.ondomcontentready=function(){} 이 트릭을 수행해야 하지만 완전한 브라우저 호환성이 없습니다.

jQuery min을 사용해야하는 것 같습니다.


maxhud

출처 : http:www.stackoverflow.com/questions/9899372/pure-javascript-equivalent-of-jquerys-ready-how-to-call-a-function-when-t

반응형