전체 페이지가로드되기 전에 약간의 자바 스크립트를 실행하고 싶습니다. 이게 가능해? 아니면 코드가 실행되기 시작 </html>
합니까?
답변
뿐만 아니라이 할 수있는 당신,하지만 당신은 특별한 노력을 할 필요가 없습니다 당신이 원하지 않는 경우에 있습니다. 🙂
브라우저가 script
HTML을 파싱 할 때 클래식 태그를 발견 하면 파싱을 중지하고 스크립트를 실행하는 JavaScript 인터프리터로 넘깁니다. 파서는 스크립트 실행이 완료 될 때까지 계속되지 않습니다 (스크립트가 document.write
파서가 처리해야하는 출력 마크 업을 호출 할 수 있기 때문 ).
이것이 기본 동작이지만 스크립트 실행을 지연하는 몇 가지 옵션이 있습니다.
-
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와 같은 번 들러를 사용할 수 있습니다.
-
defer
클래식 스크립트 태그에 속성을 사용하십시오 .<script defer src="./my-code.js"></script>
모듈
my-code.js
과 마찬가지로 HTML 구문 분석과 동시에 코드를 가져 와서 구문 분석하지만 HTML 구문 분석이 완료 될 때까지 실행 되지 않습니다 . 그러나 ,defer
외부 파일을 통해 참조에서만 인라인 스크립트 내용으로 작동하지 않습니다src
. -
나는 그것이 무엇인지 생각하지 않습니다 당신이 원하는,하지만 당신은 사용
async
되는 HTML 구문 분석이 완료되지 않은 경우에도 HTML 구문 분석과 병행하여 자바 스크립트 코드를 가져 브라우저에게 속성을, 그러나 가능한 한 빨리 실행 . 당신은 그것을 넣을 수 있습니다type="module"
태그 또는 대신에 사용할defer
고전에script
태그입니다. -
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
.)
이 현대 세계에서는 DOMContentLoaded
PrototypeJS, jQuery, ExtJS, Dojo 및 대부분의 다른 회사가 그날 제공 한 (그리고 여전히 제공하는) “준비된”기능 의 이벤트에 실질적인 가치가 없습니다 . 모듈 또는 defer
. 심지어 하루에 다시 그들을 사용하는별로 이유가 있었다 (그리고 그들은 종종 페이지 (가) 때문에 전체 jQuery 라이브러리를로드하는 동안 프리젠 테이션 들고, 잘못 사용 된 script
에 있던 head
문서 후에 대신에) 뭔가 일부 개발자의를 Google은 초기에 신고했습니다. 이것은 또한 이유의 일부 YUI 추천 의 말에 스크립트를 넣어 body
다시 하루에.
답변
언제든지 자바 스크립트 코드를 실행할 수 있습니다. AFAIK 브라우저가 <script> 태그에 도달하는 순간 실행됩니다. 그러나 아직로드되지 않은 요소에는 액세스 할 수 없습니다.
따라서 요소에 대한 액세스가 필요한 경우 DOM이로드 될 때까지 기다려야합니다 (이미지 및 항목을 포함하여 전체 페이지가로드되는 것을 의미하지는 않습니다. 훨씬 일찍로드되는 문서의 구조 일 뿐이므로 일반적으로 이겼습니다. 지연을 알지 못함), jQuery에서 DOMContentLoaded
와 같은 이벤트 또는 함수를 사용합니다 $.ready
.