최근에 JavaScript 프레임 워크를 작성하고 있습니다. 방금 DomContentLoaded 이벤트를 캡슐화했는데 조금 흥분했습니다. 나는 개발 과정에서 발생하는 원리와 호환성 문제에 대해 메모하여 모든 곳에서 잊어 버렸습니다.
JS 코드를 작성하면 일반적으로 getElementById, getElementsByTagName 및 기타 메소드를 사용하여 DOM이로드 된 후 작동을위한 DOM 요소를 선택하는 Window.onload 이벤트를 추가합니다. 그러나 Window.load는 DOM, 스크립트, CSS가로드되고 이미지 또는 Iframe의 모든 리소스가 트리거 될 때까지 기다립니다. 대부분의 경우 웹 페이지에는 더 많은 사진이 있으며 더 큽니다. 이미지를로드하는 데 시간이 오래 걸리며 JS를 실행하기에는 너무 늦었습니다. 이는 종종 사용자 경험에 영향을 미칩니다.
많은 JS 프레임 워크에는 jQuery의 $ (document) .ready () 메소드와 같은 문서가 포함되어 있으며 DOM이로드 된 직후 JS 코드를 실행하여 이미지를 천천히로드 할 수 있습니다.
Document.ready의 핵심은 DomContentLoaded 이벤트입니다. Firefox, Chrome, Opera, Safari 및 IE9+는 모두 이벤트 바인딩을 위해 addeventListener ( 'domcontentloaded', fn, false)를 사용할 수 있습니다. IE6 ~ 8은 DOMContentLoaded 이벤트를 지원하지 않으므로 IE6 ~ 8에 대한 호환 처리를 수행해야합니다.
정보에 따르면 IE6 ~ 8은 문서를 사용할 수 있습니다. iframe이 페이지에 포함되면 문서. IE6 ~ 8의 ReadyState는 Iframe의 모든 리소스가 완료되기 전에로드 될 때까지 기다립니다. 현재 Iframe은 시간이 많이 걸리는 주요 사용자가됩니다. 그러나 테스트 후 페이지에 Iframe이 없더라도 ReadyState가 완료되면 Onload 이벤트가 DomContentLoaded 이벤트 대신 실제로 트리거 되므로이 시점에서 놀랍습니다.
다행히도, 즉, 독특한 doscroll 방법이 있습니다. 페이지 DOM이로드되지 않으면 Doscroll 메소드가 호출되면 오류 가보고됩니다. 반대로, 오류가보고되지 않을 때까지 Doscroll이 간격으로 호출되는 한, 페이지가로드되었음을 의미합니다. 이 방법은 그림의 내용과 iframe이로드되었는지 여부에 관계없이 유효합니다.
브라우저가 순서대로 반복적으로 바인딩하고 수행하는 것을 방지하기 위해 여러 JS 파일이 Document.ready 이벤트에 바인딩되면 문제를 해결하기 위해 이벤트 큐 메커니즘을 도입 할 수 있습니다.
위는 문서의 원칙 및 호환성 문제입니다. 다음은 예제 코드의 단락입니다. 실행 프로세스의 이해를 용이하게하기 위해 실행 프로세스는 함수 캡슐화 모드를 사용하여 주석에 기록됩니다. 부적합한 것이 있다면 조언을 해주세요.
코드 사본은 다음과 같습니다.
// DOMREADY의 이벤트 큐를 저장합니다
eventqueue = [];
// DOM이로드되었는지 판단합니다
isready = false;
// DOMREADY가 바인딩되었는지 판단합니다
isbind = false;
/*DOMREADY () 실행
*
*@param {function}
*@execute 이벤트 핸들러를 이벤트 큐에 푸시하고 domcontentloaded를 바인딩합니다.
* DOM 로딩이 완료된 경우 즉시 실행하십시오.
*@방문객
*/
기능 domready (fn) {
if (isready) {
fn.call (창);
}
또 다른{
eventqueue.push (fn);
};
bindready ();
};
/*DOMREADY 이벤트 바인딩
*
*@param null
*@execute 최신 브라우저는 IE9+를 포함하여 addevlistener를 통해 domcontentload를 바인딩합니다
IE6-8 DOSCROLL을 판단하여 DOM이로드되었는지 여부를 결정합니다.
*@발신자 domready ()
*/
함수 bindready () {
IF (ISREADY) 반환;
if (isbind) 반환;
isbind = true;
if (window.addeventListener) {
document.addeventListener ( 'domcontentLoaded', execfn, false);
}
else if (window.attachevent) {
doscroll ();
};
};
/*Doscroll은 IE6-8의 DOM이로드되었는지 여부를 결정합니다.
*
*@param null
*@execute doscroll은 DOM이 로딩되는지 여부를 결정합니다
*@발신자 bindready ()
*/
함수 doscroll () {
노력하다{
document.documentElement.doscroll ( '왼쪽');
}
캐치 (오류) {
반환 설정 타임 아웃 (Doscroll, 20);
};
execfn ();
};
/*실행 이벤트 큐
*
*@param null
*@execute 루프 실행 이벤트 핸들러 큐에서
*@발신자 bindready ()
*/
함수 execfn () {
if (! isready) {
isready = true;
for (var i = 0; i <eventqueue.length; i ++) {
Eventqueue [i] .call (창);
};
eventqueue = [];
};
};
// js 파일 1
domready (function () {
...
});
// JS 파일 2
domready (function () {
...
});
// 비동기 적으로로드되면 DOMREADY 메소드를 바인딩하지 않으면 함수가 실행되지 않습니다.
// 비동기로드 JS 다운로드 전에 DOMCONTENTLOADED가 발사되었고 addeventListener를 실행할 때들을 수 없습니다.
테스트 페이지 : 두 개의 큰 이미지가로드되었습니다. Onload는 JS를 실행하기 전에 이미지를로드해야합니다. DOMContentLoaded는 DOM이 JS를 실행하기 위해로드 될 때까지 기다려야합니다. 로딩 프로세스를 볼 수 있도록 FireBug를 열 수 있습니다. 각 테스트 전에 브라우저 캐시를 청소해야합니다.