질문자 :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/
작동 방식을 요약하면 다음과 같습니다.
- 공개되지 않은 상태 변수를 가질 수 있도록 IIFE (즉시 호출된 함수 표현식)를 만듭니다.
- 공개 함수
docReady(fn, context)
-
docReady(fn, context)
가 호출되면 ready 핸들러가 이미 실행되었는지 확인하십시오. setTimeout(fn, 1)
끝난 직후 새로 추가된 콜백이 실행되도록 예약하십시오. - 준비 처리기가 아직 실행되지 않은 경우 이 새 콜백을 나중에 호출할 콜백 목록에 추가합니다.
- 문서가 이미 준비되었는지 확인하십시오. 그렇다면 모든 준비된 핸들러를 실행하십시오.
- 문서가 언제 준비되는지 알기 위해 아직 이벤트 리스너를 설치하지 않았다면 지금 설치하십시오.
-
document.addEventListener
가 있는 경우 "DOMContentLoaded"
및 "load"
이벤트 모두에 대해 .addEventListener()
를 사용하여 이벤트 핸들러를 설치합니다. "로드"는 안전을 위한 백업 이벤트이며 필요하지 않아야 합니다. -
document.addEventListener
"onreadystatechange"
및 "onload"
이벤트에 대해 .attachEvent()
를 사용하여 이벤트 핸들러를 설치합니다. -
onreadystatechange
이벤트에서 document.readyState === "complete"
인지 확인하고, 그렇다면 모든 준비 처리기를 실행하는 함수를 호출합니다. - 다른 모든 이벤트 처리기에서 모든 준비 처리기를 실행하는 함수를 호출합니다.
- 모든 준비 처리기를 호출하는 함수에서 상태 변수를 확인하여 이미 실행되었는지 확인합니다. 있으면 아무 것도 하지 마십시오. 아직 호출되지 않았다면 준비된 함수의 배열을 반복하고 추가된 순서대로 각 함수를 호출합니다. 모두 호출되었음을 나타내는 플래그를 설정하여 두 번 이상 실행되지 않도록 합니다.
- 사용 중인 모든 클로저를 해제할 수 있도록 함수 배열을 지우십시오.
docReady()
로 등록된 핸들러는 등록된 순서대로 실행되도록 보장됩니다.
docReady(fn)
를 호출 setTimeout(fn, 1)
사용하여 현재 실행 스레드가 완료되는 즉시 콜백이 실행되도록 예약됩니다. 이것은 JS의 현재 스레드가 종료되고 호출 순서를 유지하는 즉시 이후가 되더라도 호출 코드가 항상 나중에 호출될 비동기 콜백이라고 가정할 수 있도록 합니다.
jfriend00jQuery 없이 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
(같이 uninitialized
및 loading
, 처음 두 DOM 준비 상태를 5 점 만점) 우리는 시간 제한을 설정하고 다시 확인. 그렇지 않으면 전달된 함수를 실행합니다.
그리고 모든 브라우저에서 작동 하는 트릭에 대한 jsFiddle이 있습니다.
이를 책에 포함시킨 Tutorialzine 에 감사드립니다.
Ram PatraIE9, 최신 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 Wikiready
포함하여 많은 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이 준비되었는지 확인하는 방법 도 참조하세요. .
rogerdpackdocument.ondomcontentready=function(){}
이 트릭을 수행해야 하지만 완전한 브라우저 호환성이 없습니다.
jQuery min을 사용해야하는 것 같습니다.
maxhud출처 : http:www.stackoverflow.com/questions/9899372/pure-javascript-equivalent-of-jquerys-ready-how-to-call-a-function-when-t