2016-11-25 44 views
0

我需要動態加載JavaScript文件,然後訪問其內容。如何加載和使用/調用動態的JavaScript

文件test.js

test = function() { 
    var pub = {} 
    pub.defult_id = 1; 
    return pub; 
}() 


在這種情況下,它的工作原理:

<!DOCTYPE html> 
<html> 
<head> 
    <script type="text/javascript" src="/test.js"></script>  
</head> 
<body> 
    <script type="text/javascript"> 
     console.log(test.defult_id); 
    </script> 
</body> 
</html> 


但我需要動態加載它,這樣它不工作:

<!DOCTYPE html> 
<html> 
<head> 
</head> 
<body> 
    <script type="text/javascript"> 
     function loadjs(file) { 
      var script = document.createElement("script"); 
      script.type = "application/javascript"; 
      script.src = file; 
      document.body.appendChild(script); 
     } 
     loadjs('test.js'); 
     console.log(test.defult_id); 
    </script> 
</body> 
</html> 


錯誤:Uncaught ReferenceError: test is not defined(…)

+0

爲什麼需要'location.href '?除了客戶端訪問和當前URL以'/'結尾的問題之外,只針對'/ test.js'將與'location.href +'/ test.js'相同,例如'www.domain.com /'那麼你的javascript將會瞄準'www.domain.com // test.js' – NewToJS

+1

真的不需要'location.href'。我已經改變了。 –

回答

2

你可以不喜歡這樣:

function loadjs(file) { 
    var script = document.createElement("script"); 
    script.type = "text/javascript"; 
    script.src = file; 
    script.onload = function(){ 
     alert("Script is ready!"); 
     console.log(test.defult_id); 
    }; 
    document.body.appendChild(script); 
} 

欲瞭解更多信息,請閱讀這篇文章:https://www.nczonline.net/blog/2009/06/23/loading-javascript-without-blocking/

+0

以下是關於此主題的最佳當代文章:[深入潛入腳本加載的黑暗水域](https://www.html5rocks.com/en/tutorials/speed/script-loading) – asmmahmud

1

Dinamically加載JS文件是異步的,所以要確保你的腳本中調用一些功能之前加載,在腳本中使用onload事件:

function loadjs(file) { 
      var script = document.createElement("script"); 
      script.type = "application/javascript"; 
      script.onload=function(){ 
       //at this tine the script is loaded 
       console.log("Script loaded!"); 
       console.log(test); 
      } 
      script.src = file; 
      document.body.appendChild(script); 
     } 
3

有一個偉大的文章,這是值得www.html5rocks.com閱讀所有的人在JS腳本加載有趣 - Deep dive into the murky waters of script loading

在考慮多種可能的解決方案之後的文章中,筆者的結論是,添加JS腳本體元素的末尾是爲了避免被JS腳本從而加快網頁加載時間阻止頁面呈現最好的方式。

但是,筆者提出這些人誰不顧一切地加載和異步執行腳本的另一個很好的替代解決方案。

考慮你四個劇本,名爲script1.js, script2.js, script3.js, script4.js那麼你就可以應用異步做= FALSE:現在

[ 
    'script1.js', 
    'script2.js', 
    'script3.js', 
    'script4.js' 
].forEach(function(src) { 
    var script = document.createElement('script'); 
    script.src = src; 
    script.async = false; 
    document.head.appendChild(script); 
}); 

規格說:下載一起,儘快爲了執行所有下載。

火狐< 3.6,歌劇說:我不知道這是什麼「異步」的事情是,但它只是恰巧我執行通過JS在他們添加的順序添加腳本。

Safari 5.0說:我明白「異步」,但不明白用JS將它設置爲「false」。我會盡快按照任何順序執行腳本。

IE < 10說:不知道「異步」,但有一個解決方法,使用「onreadystatechange」。

其他所有內容:我是你的朋友,我們將按照本書的要求做到這一點。

現在,完整的代碼在IE < 10解決方法:

var scripts = [ 
    'script1.js', 
    'script2.js', 
    'script3.js', 
    'script4.js' 
]; 
var src; 
var script; 
var pendingScripts = []; 
var firstScript = document.scripts[0]; 

// Watch scripts load in IE 
function stateChange() { 
    // Execute as many scripts in order as we can 
    var pendingScript; 
    while (pendingScripts[0] && pendingScripts[0].readyState == 'loaded') { 
    pendingScript = pendingScripts.shift(); 
    // avoid future loading events from this script (eg, if src changes) 
    pendingScript.onreadystatechange = null; 
    // can't just appendChild, old IE bug if element isn't closed 
    firstScript.parentNode.insertBefore(pendingScript, firstScript); 
    } 
} 

// loop through our script urls 
while (src = scripts.shift()) { 
    if ('async' in firstScript) { // modern browsers 
    script = document.createElement('script'); 
    script.async = false; 
    script.src = src; 
    document.head.appendChild(script); 
    } 
    else if (firstScript.readyState) { // IE<10 
    // create a script and add it to our todo pile 
    script = document.createElement('script'); 
    pendingScripts.push(script); 
    // listen for state changes 
    script.onreadystatechange = stateChange; 
    // must set src AFTER adding onreadystatechange listener 
    // else we’ll miss the loaded event for cached scripts 
    script.src = src; 
    } 
    else { // fall back to defer 
    document.write('<script src="' + src + '" defer></'+'script>'); 
    } 
} 

一些技巧和縮小後,它的362個字節

!function(e,t,r){function n(){for(;d[0]&&"loaded"==d[0][f];)c=d.shift(),c[o]=!i.parentNode.insertBefore(c,i)}for(var s,a,c,d=[],i=e.scripts[0],o="onreadystatechange",f="readyState";s=r.shift();)a=e.createElement(t),"async"in i?(a.async=!1,e.head.appendChild(a)):i[f]?(d.push(a),a[o]=n):e.write("<"+t+' src="'+s+'" defer></'+t+">"),a.src=s}(document,"script",[ 
    "//other-domain.com/1.js", 
    "2.js" 
]) 
相關問題