[javascript] 전체 페이지가로드되기 전에 자바 스크립트를 실행할 수 있습니까?

전체 페이지가로드되기 전에 약간의 자바 스크립트를 실행하고 싶습니다. 이게 가능해? 아니면 코드가 실행되기 시작 </html>합니까?



답변

뿐만 아니라이 할 수있는 당신,하지만 당신은 특별한 노력을 할 필요가 없습니다 당신이 원하지 않는 경우에 있습니다. 🙂

브라우저가 scriptHTML을 파싱 할 때 클래식 태그를 발견 하면 파싱을 중지하고 스크립트를 실행하는 JavaScript 인터프리터로 넘깁니다. 파서는 스크립트 실행이 완료 될 때까지 계속되지 않습니다 (스크립트가 document.write파서가 처리해야하는 출력 마크 업을 호출 할 수 있기 때문 ).

이것이 기본 동작이지만 스크립트 실행을 지연하는 몇 가지 옵션이 있습니다.

  1. JavaScript 모듈을 사용하십시오. type="module"스크립트입니다 연기 되는 HTML이 완전히 구문 분석 될 때까지 초기 DOM이 생성되었습니다. 이것이 모듈을 사용하는 주된 이유는 아니지만 그 이유 중 하나입니다.

    <script type="module" src="./my-code.js"></script>
    <!-- Or -->
    <script type="module">
    // Your code here
    </script>
    

    코드는 가져 와서 (별도의 경우) HTML 구문 분석과 병렬로 구문 분석되지만 HTML 구문 분석이 완료 될 때까지 실행 되지 않습니다 . (모듈 코드가 자체 파일이 아닌 인라인 인 경우 HTML 구문 분석이 완료 될 때까지 연기됩니다.)

    2010 년에이 답변을 처음 작성했을 때는 사용할 수 없었지만 2020 년에는 모든 주요 최신 브라우저가 기본적으로 모듈을 지원하고 이전 브라우저를 지원해야하는 경우 Webpack 및 Rollup.js와 같은 번 들러를 사용할 수 있습니다.

  2. defer클래식 스크립트 태그에 속성을 사용하십시오 .

    <script defer src="./my-code.js"></script>

    모듈 my-code.js과 마찬가지로 HTML 구문 분석과 동시에 코드를 가져 와서 구문 분석하지만 HTML 구문 분석이 완료 될 때까지 실행 되지 않습니다 . 그러나 , defer외부 파일을 통해 참조에서만 인라인 스크립트 내용으로 작동하지 않습니다 src.

  3. 나는 그것이 무엇인지 생각하지 않습니다 당신이 원하는,하지만 당신은 사용 async되는 HTML 구문 분석이 완료되지 않은 경우에도 HTML 구문 분석과 병행하여 자바 스크립트 코드를 가져 브라우저에게 속성을, 그러나 가능한 한 빨리 실행 . 당신은 그것을 넣을 수 있습니다 type="module"태그 또는 대신에 사용할 defer고전에 script태그입니다.

  4. script문서 끝에 닫는 </body>태그 바로 앞에 태그를 넣으십시오 .

    <!doctype html>
    <html>
    <!-- ... -->
    <body>
    <!-- The document's HTML goes here -->
    <script type="module" src="./my-code.js"></script><!-- Or inline script -->
    </body>
    </html>
    

    이렇게하면 코드가 발견 되 자마자 실행되지만 위의 HTML에 정의 된 모든 요소가 존재하고 사용할 준비가됩니다.

    예전에는 script태그를 만날 때까지 코드 가져 오기를 시작하지 않기 때문에 일부 브라우저에서 추가 지연 이 발생했지만 최신 브라우저는 미리 스캔하고 미리 가져 오기를 시작합니다. 그럼에도 불구하고 이것은 현재 세 번째 선택이며 두 모듈 모두 defer더 나은 옵션입니다.

스펙은 유용한 도면 갖는 원료 나타내는 script태그를, defer, async, type="module", 및 type="module" async자바 스크립트 코드 페치를 실행할 때의 타이밍과 :

여기에 이미지 설명 입력

다음은 원시 script태그 인 기본 동작의 예입니다 .

.found {
    color: green;
}
<p>Paragraph 1</p>
<script>
    if (typeof NodeList !== "undefined" && !NodeList.prototype.forEach) {
        NodeList.prototype.forEach = Array.prototype.forEach;
    }
    document.querySelectorAll("p").forEach(p => {
        p.classList.add("found");
    });
</script>
<p>Paragraph 2</p>

( 해당 코드에 대한 자세한 내용은 여기 내 대답을 참조하십시오 NodeList.)

이를 실행하면 “Paragraph 1″이 녹색으로 표시되지만 “Paragraph 2″는 검은 색입니다. 스크립트가 HTML 구문 분석과 동 기적으로 실행되어 두 번째가 아닌 첫 번째 단락 만 찾았 기 때문입니다.

대조적으로 다음은 type="module"스크립트입니다.

.found {
    color: green;
}
<p>Paragraph 1</p>
<script type="module">
    document.querySelectorAll("p").forEach(p => {
        p.classList.add("found");
    });
</script>
<p>Paragraph 2</p>

이제 둘 다 초록색임을 주목하십시오. HTML 구문 분석이 완료 될 때까지 코드가 실행되지 않았습니다. defer script외부 콘텐츠 (인라인 콘텐츠는 아님) 에서도 마찬가지입니다 .

( NodeList모듈을 지원하는 최신 브라우저가 이미 forEach켜져 있기 때문에 거기 에서 확인할 필요가 없습니다 NodeList.)

이 현대 세계에서는 DOMContentLoadedPrototypeJS, jQuery, ExtJS, Dojo 및 대부분의 다른 회사가 그날 제공 한 (그리고 여전히 제공하는) “준비된”기능 의 이벤트에 실질적인 가치가 없습니다 . 모듈 또는 defer. 심지어 하루에 다시 그들을 사용하는별로 이유가 있었다 (그리고 그들은 종종 페이지 (가) 때문에 전체 jQuery 라이브러리를로드하는 동안 프리젠 테이션 들고, 잘못 사용 된 script에 있던 head문서 후에 대신에) 뭔가 일부 개발자의를 Google은 초기에 신고했습니다. 이것은 또한 이유의 일부 YUI 추천 의 말에 스크립트를 넣어 body다시 하루에.


답변

언제든지 자바 스크립트 코드를 실행할 수 있습니다. AFAIK 브라우저가 <script> 태그에 도달하는 순간 실행됩니다. 그러나 아직로드되지 않은 요소에는 액세스 할 수 없습니다.

따라서 요소에 대한 액세스가 필요한 경우 DOM이로드 될 때까지 기다려야합니다 (이미지 및 항목을 포함하여 전체 페이지가로드되는 것을 의미하지는 않습니다. 훨씬 일찍로드되는 문서의 구조 일 뿐이므로 일반적으로 이겼습니다. 지연을 알지 못함), jQuery에서 DOMContentLoaded와 같은 이벤트 또는 함수를 사용합니다 $.ready.


답변