Javascript在頁面載入時的執行順序

langgufu314發表於2011-09-07

Javascript在頁面載入時的執行順序
一、在HTML中嵌入Javasript的方法
    1-直接在Javascript程式碼放在標記對<script>和</script>之間
    2- 由<script />標記的src屬性制定外部的js檔案
    3- 放在事件處理程式中,比如:<p onclick="alert('我是由onclick事件執行的Javascript')">點選我</p>
    4-作為URL的主體,這個URL使用特殊的Javascript:協議,比如:<a href="javascript:alert('我是由javascript:協議執行的javascript')">點選我</a>
    5-利用javascript本身的document.write()方法寫入新的javascript程式碼
    6-利用Ajax非同步獲取javascript程式碼,然後執行

第3種和第4種方法寫入的Javascript需要觸發才能執行,所以除非特別設定,否則頁面載入時不會執行。
二、Javascript在頁面的執行順序

  1  頁面上的Javascript程式碼是HTML文件的一部分,所以Javascript在頁面裝載時執行的順序就是其引入標記<script />的出現順序, <script />標記裡面的或者通過src引入的外部JS,都是按照其語句出現的順序執行,而且執行過程是文件裝載的一部分。
    每個指令碼定義的全域性變數和函式,都可以被後面執行的指令碼所呼叫。
    變數的呼叫,必須是前面已經宣告,否則獲取的變數值是undefined。

    <script type="text/javscrpt">//<![CDATA[
    alert(tmp);  //輸出 undefined
    var tmp = 1;
    alert(tmp);  //輸出 1
    //]]></script>

    同一段指令碼,函式定義可以出現在函式呼叫的後面,但是如果是分別在兩段程式碼,且函式呼叫在第一段程式碼中,則會報函式未定義錯誤。

    <script type="text/javscrpt">//<![CDATA[
    aa();            //瀏覽器報錯
    //]]></script>
    <script type="text/javscrpt">//<![CDATA[
    aa(); //輸出 1
    function aa(){alert(1);}
    //]]></script>

    document.write()會把輸出寫入到指令碼文件所在的位置,瀏覽器解析完documemt.write()所在文件內容後,繼續解析document.write()輸出的內容,然後在繼續解析HTML文件。

    <script type="text/javascript">//<![CDATA[
        document.write('<script type="text/javascript" src="test.js"><\/script>');
        document.write('<script type="text/javascript">');
        document.write('alert(2);')
        document.write('alert("我是" + tmpStr);');
        document.write('<\/script>');
        //]]></script>
      <script type="text/javascript">//<![CDATA[
        alert(3);
        //]]></script>

    test.js的內容是:

    var tmpStr = 1;
        alert(tmpStr);

        在Firefox和Opera中的彈出值的順序是:1、2、我是1、3
        在IE中彈出值的順序是:2、1、3,同時瀏覽器報錯:tmpStr未定義

    原因可能是IE在document.write時,並未等待載入SRC中的Javascript程式碼完畢後,才執行下一行,所以導致2先彈出,並且執行到document.write(‘document.write("我是" + tmpStr)’)呼叫tmpStr時,tmpStr並未定義,從而報錯。

    解決這個問題,可以利用HTML解析是解析完一個HTML標籤,再執行下一個的原理,把程式碼拆分來實現:

    <script type="text/javascript">//<![CDATA[
        document.write('<script type="text/javascript" src="test.js"><\/script>');
        //]]></script>
      <script type="text/javascript">//<![CDATA[
        document.write('<script type="text/javascript">');
        document.write('alert(2);')
        document.write('alert("我是" + tmpStr);');
        document.write('<\/script>');
        //]]></script>
      <script type="text/javascript">//<![CDATA[
        alert(3);
        //]]></script>

    這樣IE下和其他瀏覽器輸出值的順序都是一直的了:1、2、我是1、3。


  2  IE中可以利用defer,defer作用是把程式碼載入下來,並不立即執行,等文件裝載完畢之後再執行,有點類似window.onload,但是沒有window.onload那樣的侷限性,可以重複使用,但是隻在IE中有效,所以上面的例子可以修改成為

    <script type="text/javascript">//<![CDATA[
    document.write('<script type="text/javascript" src="test.js"><\/script>');
    document.write('<script type="text/javascript" defer="defer">');
    document.write('alert(2);')
    document.write('alert("我是" + tmpStr);');
    document.write('<\/script>');
    //]]></script>
    <script type="text/javascript">//<![CDATA[
    alert(3);
    //]]></script>

    這樣IE就不報錯了,輸出值的順序變成:1、3、2、我是1
3  利用Ajax。
    因為xmlhttpRequest能判斷外部文件載入的狀態,所以能夠改變程式碼的載入順序

 

相關文章