>  기사  >  웹 프론트엔드  >  자바스크립트 로딩 및 실행

자바스크립트 로딩 및 실행

伊谢尔伦
伊谢尔伦원래의
2016-11-22 13:12:061035검색

먼저 Javascript의 로딩과 실행에 대해 이야기하고 싶습니다. 일반적으로 브라우저에는 Javascript 실행에 대한 두 가지 주요 특징이 있습니다. 1) 로드 후 즉시 실행됩니다. 2) 실행 시 페이지의 후속 콘텐츠(페이지 렌더링 및 기타 리소스 다운로드 포함)를 차단합니다. 따라서 여러 js 파일이 도입되면 브라우저의 경우 이러한 js 파일이 직렬로 로드되어 순차적으로 실행됩니다.

자바스크립트는 HTML 문서의 DOM 트리를 조작할 수 있기 때문에 브라우저는 일반적으로 CSS 파일을 병렬로 다운로드하는 것처럼 js 파일을 병렬로 다운로드하지 않습니다. 이는 js 파일의 특수성 때문입니다. 따라서 자바스크립트가 후속 DOM 요소를 작동하려는 경우 기본적으로 브라우저는 객체를 찾을 수 없다는 오류를 보고합니다. Javascript가 실행되면 후속 HTML이 차단되고 DOM 트리에 후속 DOM 노드가 없기 때문입니다. 그래서 프로그램에서 오류를 보고했습니다.

전통적인 방식

그래서 코드에 다음 코드를 작성하면

<scripttype="text/javascript"  src="http://coolshell.cn/asyncjs/alert.js"></script>

기본적으로 헤드에 5e0938f6078d2452dc2048f0cba58efa 태그를 document.write한 후에는 다음 작업을 실행할 수 있다고 생각할 수도 있습니다. 이는 맞습니다. 이는 동일한 스크립트 태그의 Javascript 코드에 해당되지만 전체 페이지에서는 여전히 차단됩니다. 다음은 테스트 코드입니다.

<scripttype="text/javascript"language="javascript">
    function loadjs(script_filename) {
        document.write(&#39;<&#39; + &#39;script language="javascript" type="text/javascript"&#39;);
        document.write(&#39; src="&#39; + script_filename + &#39;">&#39;);
        document.write(&#39;<&#39;+&#39;/script&#39;+&#39;>&#39;);
        alert("loadjs() exit...");
    }
    var script = &#39;http://coolshell.cn/asyncjs/alert.js&#39;;
    loadjs(script);
    alert("loadjs() finished!");
</script>
<scripttype="text/javascript"language="javascript">
   alert("another block");
</script>

알림 순서가 어떻게 된다고 생각하시나요? 다양한 브라우저에서 시도해 볼 수 있습니다. 닫으려는 테스트 페이지는 다음과 같습니다. 예 2.

스크립트 지연 및 비동기 속성

IE는 IE6부터 다음과 같은 지연 태그를 지원했습니다.

<scriptdefertype="text/javascript"src="./alert.js">
</script>

IE의 경우 이 태그는 IE가 js 파일을 병렬로 다운로드하고 전체 DOM이 로드될 때까지(DOMContentLoaded) 다중 defer 3f1c4e4b6b16bbbd69b2ee476dc4f83a도 실행됩니다. 가장 중요한 점은 3f1c4e4b6b16bbbd69b2ee476dc4f83a를 defer에 추가한 후에는 후속 DOM 렌더링을 차단하지 않는다는 것입니다. 그러나 이 연기는 IE에만 ​​적용되므로 일반적으로 덜 사용됩니다.

또한 표준 HTML5에는 javascript의 비동기 로딩을 위한 속성인 async가 추가되어 있습니다. 어떤 값을 지정하든 상관없이 js 파일을 비동기적으로 로딩하기 시작합니다. 그러나 async의 비동기 로딩은 "로딩 후 즉시 실행"이라는 군사 규칙을 충실히 구현한다는 심각한 문제가 있습니다. 따라서 페이지 렌더링을 차단하지는 않지만 순서와 타이밍을 제어할 수는 없습니다. 그의 처형. 이 예를 살펴보면서 느낌을 얻을 수 있습니다.

비동기 태그를 지원하는 브라우저는 Firefox 3.6+, Chrome 8.0+, Safari 5.0+, IE 10+입니다. Opera는 아직(여기서부터) 지원하지 않으므로 이 방법은 별로 좋지 않습니다. 왜냐하면 모든 브라우저가 그것을 할 수 있는 것은 아니기 때문입니다.

DOM 방식의 동적 생성

아마도 이 방식이 가장 많이 사용되는 방식일 것입니다.

functionloadjs(script_filename) {
    varscript = document.createElement(&#39;script&#39;);
    script.setAttribute(&#39;type&#39;,&#39;text/javascript&#39;);
    script.setAttribute(&#39;src&#39;, script_filename);
    script.setAttribute(&#39;id&#39;,&#39;coolshell_script_id&#39;);
    script_id = document.getElementById(&#39;coolshell_script_id&#39;);
    if(script_id){
        document.getElementsByTagName(&#39;head&#39;)[0].removeChild(script_id);
    }
    document.getElementsByTagName(&#39;head&#39;)[0].appendChild(script);
}
varscript =&#39;http://coolshell.cn/asyncjs/alert.js&#39;;
loadjs(script);

이 방법은 js 파일을 비동기적으로 로드하는 표준 방법이 되었습니다. 이 방법에 대한 데모는 예제 3을 참조하세요. 이 방법은 JSONP에서도 활용되었습니다. 즉, 스크립트의 src에 대해 배경 스크립트(예: PHP)를 지정할 수 있으며, 이 PHP는 매개변수가 json 문자열인 자바스크립트 함수를 반환하고 사전 정의된 자바스크립트 호출을 반환합니다. 기능. 다음 예를 살펴보세요: t.js (이 예는 이전에 Weibo에서 수집한 비동기 ajax 호출의 작은 예입니다.)

요청 시 비동기식으로 js 로드

위의 DOM 메소드 예제는 Javascript의 비동기 로딩 문제를 해결하지만, 우리가 지정한 타이밍에 실행되기를 원하는 문제는 해결하지 못합니다. 따라서 위의 DOM 메소드를 특정 이벤트에만 연결하면 됩니다.

예:

window.load 이벤트에 바인딩 - 예제 4

예제 4와 예 3의 실행 차이점을 비교해야 합니다. 나는 두 예 모두에서, 코드 하이라이팅 자바스크립트를 구체적으로 사용합니다. 코드 하이라이팅 스크립트 실행과 제 Alert.js 실행을 보시면 차이를 아실 겁니다.)

window.load = loadjs("http://coolshell.cn/asyncjs/alert.js")

연결하세요. 특정 이벤트 - 예시 5

<p style="cursor: pointer"onclick="LoadJS()">Click to load alert.js </p>

    这个示例很简单了。当你点击某个DOM元素,才会真正载入我们的alert.js。

更多

但是,绑定在某个特定事件上这个事似乎又过了一点,因为只有在点击的时候才会去真正的下载js,这又会太慢了了。好了,到这里,要抛出我们的终极问题——我们想要异步地把js文件下载到用户的本地,但是不执行,仅当在我们想要执行的时候去执行。

要是我们有下面这样的方式就好了:

varscript = document.createElement("script");
script.noexecute =true;
script.src ="alert.js";
document.body.appendChild(script);
//后面我们可以这么干
script.execute();

    可惜的是,这只是一个美丽的梦想,今天我们的Javascript还比较原始,这个“JS梦”还没有实现呢。

所以,我们的程序员只能使用hack的方式来搞。

有的程序员使用了非标准的script的type来cache javascript。如:

<scripttype=cache/scriptsrc="./alert.js"></script>

    因为”cache/script”,这个东西根本就不能被浏览器解析,所以浏览器也就不能把alert.js当javascript去执行,但是他又要去下载js文件,所以就可以搞定了。可惜的是,webkit严格符从了HTML的标准——对于这种不认识的东西,直接删除,什么也不干。于是,我们的梦又破了。

所以,我们需要再hack一下,就像N多年前玩preload图片那样,我们可以动用object标签(也可以动用iframe标签),于是我们有下面这样的代码:

functioncachejs(script_filename){
    varcache = document.createElement(&#39;object&#39;);
    cache.data = script_filename;
    cache.id ="coolshell_script_cache_id";
    cache.width = 0;
    cache.height = 0;
    document.body.appendChild(cache);
}

    然后,我们在的最后调用一下这个函数。请参看一下相关的示例:示例六

在Chrome下按 Ctrl+Shit+I,切换到network页,你就可以看到下载了alert.js但是没有执行,然后我们再用示例五的方式,因为浏览器端有缓存了,不会再从服务器上下载alert.js了。所以,就能保证执行速度了。

关于这种preload这种东西你应该不会陌生了。你还可以使用Ajax的方式,如:

varxhr =newXMLHttpRequest();
xhr.open(&#39;GET&#39;,&#39;new.js&#39;);
xhr.send(&#39;&#39;);

    到这里我就不再多说了,也不给示例了,大家可以自己试试去。

最后再提两个js,一个是ControlJS,一个叫HeadJS,专门用来做异步load javascript文件的。


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.