2009-12-18 1 views
25

동적 페이지로드를 사용하여 초기 페이지로드 시간을 줄입니다. 스크립트에 의해 정의 된 함수와 객체가 액세스 가능하도록 스크립트가 완전히로드되었는지 확인해야합니다.script.readyState가 동적 스크립트로드 종료를 감지하도록 신뢰할 수 있습니까?

나는이 목적으로 my own Javascript library을 개발 했으므로이 주제에 대한 많은 연구를 수행하여 다른 라이브러리에서 어떻게 수행되는지 연구했습니다.

이 LABjs (그리고 다른 많은 로더) 알고, 모든 스크립트 요소 "온로드"모두와 "을 onreadystatechange" 설정 :이 문제와 관련된 논의 중에 는 카일 심슨, LABjs의 저자는 밝혔다

// Attach handlers for all browsers 
script.onload = script.onreadystatechange = function(){ 
    if (!done && (!this.readyState || 
    this.readyState == "loaded" || this.readyState == "complete")) { 
     done = true; 
     success(); 
     complete(); 

     // Handle memory leak in IE 
     script.onload = script.onreadystatechange = null; 
     head.removeChild(script); 
    } 
}; 
012 : 것을

당신은 the current version of jQuery as of this writing, v1.3.2이의 예를 찾을 수 있습니다 ... 일부 브라우저를 발사하며, 일부 은 다른 발사합니다

이것은 최신 기술이지만 Opera 9.64의 이상한 동작을 분석하는 동안이 기술을 사용하면 onload 콜백이 너무 일찍 시작된다는 결론에 도달했습니다.

이 질문에 대한 답변으로 내 자신의 연구 결과를 게시하고 커뮤니티에서 더 많은 증거와 의견을 수집하고자합니다.

+0

누구나 jQuery 1.x-master 분기에서 현재 코드를 찾습니다. 그들은'.onreadystatechange'와'.onload'를 사용하지 않고 약속들로 대체 한 것처럼 보입니다. [Clicky] (https://github.com/jquery/jquery/blob/1.x-master/src/ajax.js) – Campbeln

답변

7

Opera에서 script.readyState 속성을 신뢰할 수 없습니다. 예를 들어, 스크립트가 Opera 9.64에서 실행되기 전에 "loaded"라는 readyState가 실행될 수 있습니다.

나는 Opera 9에서 the same test을 수행했습니다.64와 오페라 10, 다른 결과.

오페라 9.64에서 onreadystatechange 처리기는 스크립트가 실행되기 전후에 한 번, 두 번 실행됩니다.

# Fri Dec 18 2009 17:54:43 GMT+0100 
# Opera/9.64 (Windows NT 5.1; U; en) Presto/2.1.1 
Test for script.readyState behavior started 
Added script with onreadystatechange handler 
readystatechange: loaded 
test1.js: Start 
test1.js: Start of closure 
test1.js: End of closure 
readystatechange: loaded 

오페라 10에서을 onreadystatechange 핸들러가 여전히 값을 두 번 발사됩니다 "다음 readyState의 속성은이 값이 스크립트로드의 끝을 감지하는 신뢰할 수없는 즉, 두 경우 모두에서"로드 "입니다 "로드하지만, 스크립트 후 두 번 실행 :

# Fri Dec 18 2009 18:09:58 GMT+0100 
# Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.10 
Test for script.readyState behavior started 
Added script with onreadystatechange handler 
test1.js: Start 
test1.js: Start of closure 
test1.js: End of closure 
readystatechange: loaded 
readystatechange: loaded 

이 다른 행동이 오페라에서 스크립트로드의 끝을 감지하는 신뢰할 수있는 방법을 onreadystatechange되지 않기 때문입니다. Opera는 onload listener도 지원하기 때문에이 다른 메커니즘을 대신 사용해야합니다.

이러한 테스트 결과에 따라 onreadystatechange는 Internet Explorer에서 스크립트로드가 끝나는 지 확인하는 데에만 사용해야하며 다른 브라우저에서는 설정하지 않아야합니다.

+0

적어도 첫 번째 이벤트는 무시해도됩니다. –

+2

@Justin Johnson은 어색해 보입니다. "로드 된"이벤트를 셀 수 있습니까? –

3

Firefox, Safari 및 Chrome에서 onreadystatechange 핸들러가 호출됩니다. , I 파이어 폭스 2, 파이어 폭스 3, 파이어 폭스, 사파리 3 로컬 파일에 테스트를 수행

<script type="text/javascript" language="javascript"> 
bezen.log.info(new Date(),true); 
bezen.log.info(navigator.userAgent,true); 

// Activate logs 
bezen.log.on(); 
bezen.log.info('Test for script.readyState behavior started'); 

var script = document.createElement('script'); 
script.src = 'test1.js'; 
script.onreadystatechange = function(){ 
    bezen.log.info('readystatechange: '+script.readyState); 
}; 
document.body.appendChild(script); 
bezen.log.info('Added script with onreadystatechange handler'); 
</script> 

:

는 I에서만을 onreadystatechange 핸들러 세트 동적 스크립트 작성 짧은 테스트 케이스를 만들어 Safari 4 및 Chrome 3과 유사한 결과가 나타났습니다 (여기에서는 FF 3.5에 기록 된 로그가 있습니다).

Fri Dec 18 2009 17:53:58 GMT+0100 
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 
Test for script.readyState behavior started 
Added script with onreadystatechange handler 
test1.js: Start 
test1.js: Start of closure 
test1.js: End of closure 

onreadystatechange는 결코 호출되지 않습니다. 이러한 브라우저에서는 onload listener 만 스크립트로드 종료를 감지하는 데 유용하며 onreadystatechange는 필요하지 않습니다.

1

Internet Explorer에서 onreadystatechange 처리기는 스크립트가 끝난 후 예상대로 작동합니다. 로모그래퍼, 여기

Fri Dec 18 18:14:51 UTC+0100 2009 
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729) 
Test for script.readyState behavior started 
Added script with onreadystatechange handler 
test1.js: Start 
test1.js: Start of closure 
test1.js: End of closure 
readystatechange: complete 

:

나는이 세 가지 브라우저에서 유사한 결과로, 인터넷 익스플로러 6, Internet Explorer 7 및 Internet Explorer 8에 (여기 익스플로러 6 인터넷에 기록 된 로그)에 same test을 수행 로컬 파일을 사용하여 테스트하면 readyState는 항상 "완료"되며 몇 페이지를 새로 고친 후에도 여전히 동일합니다.

그러나 this post by Nicholas C. Zakas에서 언급했듯이 상황에 따라 "로드 됨"및 "완료 됨"또는 "로드 됨"을 볼 수도 있습니다.

1

나는 인터넷 익스플로러 (9에서 테스트)가 readyState === 'loaded'일 때 항상 스크립트를 준비하지 못한다는 것을 알아 냈습니다. 나는이 이벤트 핸들러를 사용하여 성공했다. (물론 9 개) onactivate. 전에 내 머리카락을 꺼내고 있었다.

0

Chrome에서도 유사한 결과가 나타납니다.

그냥 온로드와의 OnError ... onready하지 않습니다.

관련 문제