本文實例講述了js實作動態載入腳本的方法。分享給大家參考,具體如下:
最近公司的前端地圖產品需要做一下模組劃分,希望用戶用到哪一塊的功能再加載哪一塊的模組,這樣可以提高用戶體驗。
所以到處查資料研究js動態腳本的加載,不過真是讓人傷心啊! ,網路上幾乎都是同一篇文章,4種方法,討厭其中拷貝別人成果的人,也不加個原文的連結。哎!關鍵是最後一種方法還有點錯誤。經過兩天的研究查閱資料,在這裡和大家分享一下。
首先我們需要一個被載入的js文件,我在一個固定資料夾下建立了一個package.js,打開後在裡面寫一個方法functionOne,很簡單,程式碼如下:
function functionOne(){ alert("成功加载"); }
後面的html檔案都建立在同一個目錄下。
方法一:直接document.write
在同一個資料夾下方建立一個function1.html,程式碼如下:
<html> <head> <title></title> <script type="text/javascript"> function init() { //加载js脚本 document.write("<script src='package.js'><\/script>"); //加载一个按钮 document.write("<input type=\"button\" value=\"测试运行效果\" onclick=\"operation()\"\/>"); //如果马上使用会找不到,因为还没有加载进来,此处会报错 functionOne(); } function operation() { //可以运行,显示“成功加载” functionOne(); } </script> </head> <body> <input type="button" value="初始化加载" onclick="init()"/> </body> </html>
透過document.write的方式可以往頁面寫入腳本,如程式碼所示,點擊按鈕「初始化載入」後可以載入package.js文件,但立即運行裡面的方法functionOne會找不到此方法,報告錯誤,而點擊第二個按鈕(透過document.write動態建立的「測試運行效果」)發現可以執行,此時腳本已經載入完畢了。由於這種方式是非同步載入(一邊繼續後面的程式碼,一邊額外開一個執行緒執行需要載入的腳本),並且document.write會重寫介面,明顯不實用。
方法二:動態改變已有script的src屬性
在同一個資料夾下方建立一個function2.html,程式碼如下:
<html> <head> <title></title> <script type="text/javascript" id="yy" src=""></script> <script type="text/javascript"> function init() { yy.src = "package.js"; //如果马上使用会找不到,因为还没有加载进来,此处会报错 functionOne(); } function operation() { //可以运行,显示“成功加载” functionOne(); } </script> </head> <body> <input type="button" value="测试按钮" onclick="init()"/> <input type="button" value="测试运行效果" onclick="operation()"/> </body> </html>
此種方法的好處是不會改變介面元素,不至於重寫介面元素,但是同樣是非同步加載,會有同樣的問題。
方法三:動態建立script元素(非同步)
在同一個資料夾下方建立一個function3.html,程式碼如下:
<html> <head> <title></title> <script type="text/javascript"> function init() { var myScript= document.createElement("script"); myScript.type = "text/javascript"; myScript.src="package.js"; document.body.appendChild(myScript); //如果马上使用会找不到,因为还没有加载进来 functionOne(); } function operation() { //可以运行,显示“成功加载” functionOne(); } </script> </head> <body> <input type="button" value="测试按钮" onclick="init()"/> <input type="button" value="测试运行效果" onclick="operation()"/> </body> </html>
此辦法的優勢相對於第二種而言就是不需要最開始就在介面寫一個script標籤,缺點還是非同步加載,存在同樣的問題。
這三種方法都是非同步執行的,所以在載入這些腳本的同時,主頁面的腳本繼續運行,如果用以上的方法,那下面的程式碼將不會得到預期的效果。
不過可以在functionOne前面加一個alert就可以堵塞一下主頁面腳本的運行,然後你發現functionOne就可以運行了,或者你的後期代碼需要在另一個按鈕下執行,一步一步的來,要么就定義一個計時器,在固定時間後再執行後面的程式碼,不過在專案裡面絕對不可能使用這些方法。
其實第三種方法改一點就變成同步載入了。
方法四:動態建立script元素(同步)
在同一個資料夾下方建立一個function4.html,程式碼如下:
<html> <head> <title></title> <script type="text/javascript"> function init() { var myScript= document.createElement("script"); myScript.type = "text/javascript"; myScript.appendChild(document.createTextNode("function functionOne(){alert(\"成功运行\"); }")); document.body.appendChild(myScript); //此处发现可以运行 functionOne(); } </script> </head> <body> <input type="button" value="测试按钮" onclick="init()"/> </body> </html>
此方法並沒有載入外部的js文件,而是為myScript添加了子項。在Firefox、Safari、Chrome、Opera和IE9中,這些程式碼可以正常運作。但是在IE8以及以下的版本會導致錯誤。 IE將