Javascript在頁面加載時的執行順序(轉載)

原文:http://dancewithnet.com/2007/03/22/order-of-execution-of-javascript-on-web/

一、在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,都是按照其語句出現的順序執行,而且執行過程是文檔裝載的一部分。
  2. 每個腳本定義的全局變量和函數,都可以被后面執行的腳本所調用。
  3. 變量的調用,必須是前面已經聲明,否則獲取的變量值是undefined。
    <script type="text/javscrpt">//<![CDATA[
    alert(tmp);  //輸出 undefined
    var tmp = 1;
    alert(tmp);  //輸出 1
    //]]></script>
  4. 同一段腳本,函數定義可以出現在函數調用的后面,但是如果是分別在兩段代碼,且函數調用在第一段代碼中,則會報函數未定義錯誤。
    <script type="text/javscrpt">//<![CDATA[
    aa();            //瀏覽器報錯
    //]]></script>
    <script type="text/javscrpt">//<![CDATA[
    aa();            //輸出 1 
    function aa(){alert(1);}
    //]]></script>
  5. 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。

三、如何改變Javascript在頁面的執行順序

    1. 利用onload
      <script type="text/javascript">//<![CDATA[
      window.onload = f;
      function f(){alert(1);}
      alert(2);
      //]]></script>

      輸出值順序是 2、1。

      需要注意的是,如果存在多個winodws.onload的話,只有最有一個生效,解決這個辦法是:

      window.onload = function(){f();f1();f2();.....}
      利用2級DOM事件類型
      if(document.addEventListener){
      window.addEventListener('load',f,false);
      window.addEventListener('load',f1,false);
      ...
      }else{
      window.attachEvent('onload',f);
      window.attachEvent('onload',f1);
      ...
      }
    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

      當HTML解析器遇到一個腳本,它必須按常規終止對文檔的 解析并等待腳本執行。為了解決這個問題HTML4標準定義了defer。通過defer來提示瀏覽器可以繼續解析HTML文檔,并延遲執行腳本。這種延遲 在腳本從外部文件載入時非常有用,讓瀏覽器不必等待外部文件全部載入之后才繼續執行,能有效的提高性能。IE是目前唯一支持defer屬性的瀏覽器,但 IE并沒有正確的實現了defer屬性,因為延遲的腳本總是被延遲,直到文檔結束,而不是只延遲到下一個非延遲的腳本。這意味著,IE中延遲的腳本的執行 順序相當混亂,并且不能定義任何后面非延遲腳本并須的函數和變量。在IE中所有的defer的腳本執行時間應該都是HTML文檔樹建立以 后,window.onload之前。
    3. 利用Ajax。
      因為xmlhttpRequest能判斷外部文檔加載的狀態,所以能夠改變代碼的加載順序。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/276197.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/276197.shtml
英文地址,請注明出處:http://en.pswp.cn/news/276197.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

TClientDataSet[27]: 字段值的約束(或叫輸入限制)

Required、Precision、MaxValue、MinValue:begin{ Required: 必填字段 }with TIntegerField.Create(Self) do beginFieldName : ID;Required : True;DataSet : ClientDataSet1;end;{ Precision: 浮點數精度}with TFloatField.Create(Self) do beginFieldName : Float;Precision…

年度總結文章的抽獎結果公布

大家好&#xff0c;我是若川。2月4日&#xff0c;發表了我的2020年度總結文章《若川的2020年度總結&#xff0c;水波不興》&#xff0c;本以為閱讀量應該突破一千會比較快&#xff0c;實際上比較艱難&#xff0c;而且還掉粉10來人。2020年運營公眾號以來&#xff0c;不知不覺發…

php 正則表達式 匹配中日韓字符(GBK)

轉載鏈接&#xff1a;http://www.cnblogs.com/ITEagle/archive/2013/01/14/2859775.html 首先是這些非英文字符的編碼范圍&#xff1a; 這里是幾個主要非英文語系字符范圍 2E80&#xff5e;33FFh&#xff1a;中日韓符號區。收容康熙字典部首、中日韓輔助部首、注音符號、日本假…

linux多線程求和_linux 多線程信號處理總結

linux 多線程信號總結(一)1. 在多線程環境下&#xff0c;產生的信號是傳遞給整個進程的&#xff0c;一般而言&#xff0c;所有線程都有機會收到這個信號&#xff0c;進程在收到信號的的線程上下文執行信號處理函數&#xff0c;具體是哪個線程執行的難以獲知。也就是說&#xff…

Elon Musk

人物事件 成長學習 1971年6月28日&#xff0c;埃隆馬斯克在南非的比勒陀利亞出生&#xff0c;他的 埃隆馬斯克 父親是一名南非機電工程師&#xff0c;母親是加拿大人&#xff0c;從事營養師兼模特。[8] 1981年&#xff0c;10歲的馬斯克就擁有了自己的第一臺電腦&#xff0c;并…

真誠推薦這7個大佬的公眾號,碎片化學習

逆水行舟&#xff0c;不進則退。我們的工作已經占用了大塊的時間了&#xff0c;剩下的只有各種碎片&#xff0c;最適合碎片時間學習的&#xff0c;莫過于優質的技術干貨公眾號啦~以下這些是小編精選&#xff0c;里面有很多資訊和資源&#xff0c;內含干貨&#xff0c;希望能給大…

[轉]Windows 7 產品密鑰是否安全

提到Windows 7&#xff08;或Windows Server 2008&#xff09;有些人認為自己的產品密鑰&#xff08;Product Key&#xff09;很安全&#xff0c;甚至在公司內部有些網管也認為公司部署的Windows 7 系統的密鑰不會泄露。但其實并非如此&#xff0c;眾所周知我們的密鑰都是寫在注…

HttpWatch的Result中出現Aborted的原因分析[配圖]

轉載鏈接&#xff1a;http://www.cnblogs.com/yutiansanshou/archive/2013/02/01/2889486.html 我們在使用HttpWatch進行Web調試的過程中有時候會看到非HTTP Status Code&#xff08;狀態碼&#xff09;的值&#xff0c; 例如&#xff1a;(Aborted)。 (Aborted)是HttpWatch中定…

android顯示布局邊界的邊距_Android設計規范 Material Design-Layout(2 度量與邊框)

度量與邊框基準網絡所有組件都與間隔為8dp的基準網格對齊。排版/文字(Type)與間隔為4dp的基準網格對齊。在工具條中的圖標同樣與間隔為4dp的基準網格對齊。這些規則適用于移動設備、平板設備以及桌面應用程序。有關詳細信息請參見組件一節。有關詳細信息請參見字體排版一節。邊…

《大規模分布式系統架構與設計實戰》

《大規模分布式系統架構與設計實戰》 基本信息 作者&#xff1a; 彭淵 叢書名&#xff1a; 大數據技術叢書 出版社&#xff1a;機械工業出版社 ISBN&#xff1a;9787111455035 上架時間&#xff1a;2014-2-21 出版日期&#xff1a;2014 年2月 開本&#xff1a;16開 頁碼&…

WINDOWS下的squid

今天寫這篇教程目的在于分享自己在WINDOWS主機下配置squid的方法。哪些地方寫的不完善或是不完整或是需要修改的地方&#xff0c;大家可以提出。我會第一時間糾正。下面看正文部分。先提條件&#xff0c;您預安裝配置squid的這臺計算機必須是聯入網絡的&#xff0c;系統版本是w…

Provide/inject 真的可以取代 Vuex 嗎?

Hello&#xff0c;各位小伙伴&#xff0c;接下來的一段時間里&#xff0c;我會把我的課程《Vue.js 3.0 核心源碼解析》中問題的答案陸續在我的公眾號發布&#xff0c;由于課程的問題大多數都是開放性的問題&#xff0c;所以我的答案也不一定是標準的&#xff0c;僅供你參考喔。…

php 計算代碼執行時間

轉載鏈接&#xff1a;http://blog.csdn.net/php_boy/article/details/6450678 class runtime {var $StartTime 0;var $StopTime 0;function get_microtime(){list($usec, $sec) explode( , microtime());return ((float)$usec (float)$sec);}function start(){$this->S…

參數方程求二階偏導_偏微分方程

常微分方程&#xff08;ODE&#xff09; 的時候我們更多是關于時間的導數。偏微分方程&#xff08;partial differential equation) 則不僅僅是與時間相關&#xff0c;加上了與空間位置相關的一些信息。解當 ODE 滿足 利普希茨連續&#xff08;Lipschitz continuity&#xff09…

Spring Batch 批量處理策略

為了幫助設計和實現批量處理系統&#xff0c;基本的批量應用是通過塊和模式來構建的&#xff0c;同時也應該能夠為程序開發人員和設計人員提供結構的樣例和基礎的批量處理程序。當你開始設計一個批量作業任務的時候&#xff0c;商業邏輯應該被拆分一系列的步驟&#xff0c;而這…

CString原理介紹

看了很多人寫的程序,包括我自己寫的一些代碼&#xff0c;發現很大的一部分bug是關于MFC類中的CString的錯誤用法的.出現這種錯誤的原因主要是對CString的實現機制不是太了解。 CString是對于原來標準c中字符串類型的一種的包裝。因為&#xff0c;通過很長時間的編程&#xff0c…

如何從零開始開發一個 Chrome 插件?

什么是瀏覽器插件&#xff1f;簡單來說瀏覽器插件&#xff0c;是瀏覽器上的一種工具&#xff0c;可以提供一些瀏覽器沒有的功能&#xff0c;幫你做一些有趣的事情。開發者可以根據自己的喜歡&#xff0c;去實現一些功能。插件基于Web技術&#xff08;html、css、js&#xff09;…

mysql 重復字段查詢及排除重復值

轉載鏈接&#xff1a;http://blog.sina.com.cn/s/blog_3edc5e2e010131ys.html mysql 重復字段查詢及排除重復值 SELECT a.id,a.title FROM dede_archives a left join dede_taglist t on t.taga.title WHERE t.typeid$id and t.arcrank>-1 and a.typeid28 group by t.tag; …

swiper移入暫停_react中swiper注意事項及鼠標劃入停止輪播

首先是實例化swiper這里有一個注意點&#xff0c;就是實例化的時機如果你的swiper內容是寫死的&#xff0c;可以在componentDidMount中實例化&#xff0c;但是如果你的內容是通過接口異步請求過來的&#xff0c;就必須在componentDidUpdate里實例化&#xff0c;因為如果在 comp…

轉Excel的一種簡單方法

寫了這么久的程序﹐越來越喜歡那種簡單的解決方法﹐這段時間在做一個報表系統﹐其中有需要轉Excel﹐而且要求兼容openoffice﹐遂利用asp語法,asp.net的控件封裝特性以及excel 2003的xml試算清格式做了一個看起來比較"清爽"的excel轉檔方案。一.開始原理很簡單﹐excel…