簡體   English   中英

不能包含多個js文件。 Onload事件僅針對最后一個文件觸發,但與我擁有文件的次數相同。 怎么解決呢?

[英]Can't include more than one js file. Onload event fires only for the last file but as many times as I have files. How to solve it?

我想動態附加幾個js文件。 每個文件都有一個函數定義,我想將其代碼保存在對象的屬性中。 我使用普通的JavaScript和script標簽。 但是onload事件無法正常運行。 如果我僅包含一個文件,則一切正常。 但是,如果超過一個,則onload會發生故障。 這是我的代碼,它是對象中的方法:

// My files I want to include:
one.js
   function one() { alert('one') };

two.js
   function two() { alert('two') };

// My code in the object 
var one = null;
var two = null;   // In these properties I want to save my functions

function inc(files) {   // 'files' is the object {one: 'one', two: 'two'}
                        'one' and 'two' are names of function in my files
    for (key in files) {

       var script = document.createElement('script');
       script.setAttribute('type', 'text/javascript');

       var fullPath = '/path/to/file/' + files[key] + '.js';   // /path/to/file/one.js, /path/to/file/two.js,
       script.setAttribute('src', fullPath);


       // And here's my eventhandler. After the script is loaded,
       // names of my functions are in global scope. So, the task is:
       // to take them and save in properties using setter.
       script.onload = function() {

           setProps(window[files[key]]);   // setProp(window.one / window.two);
           window[files[key]] = null;      // remove them from global scope

           alert(one/two);   // to check if I have functions saved in properties
       }

       document.getElementsByTagName('head').item(0).appendChild(script);

    };
};

正如我在一開始所說的,如果我加載一個文件,一切都會正常。 但是對於一個以上的文件, onload可以工作兩次,但僅對我的第二個文件有效-函數定義為'two' Alert觸發兩次,並顯示代碼'two' 我的屬性'two'只有一個函數'two' ,我用參數傳遞的最后一個。 並且文件被附加在DOM中。

我嘗試在for/in循環外創建<script>標記,甚至創建了一個數組並將兩個腳本中的每個腳本分別保存為該數組的單獨元素,但這也無濟於事-僅最后一個文件位於onload和兩次。

問題是什么? 為什么對兩個文件不起作用? 有可能解決嗎?

很難確定何時不包括完整的代碼,但是很可能您遇到了關閉問題。

您在for循環中定義了onload函數,這意味着它將綁定對“ key”局部變量的引用。 到“卸載”功能實際運行時,for循環將已完成,“鍵”將為“兩個”,因此您將在兩個警報中看到“兩個”。

這是相同問題的更簡單的示例:

for (x=0; x< 2; x++) {
   setTimeout(function() {
       alert(x);
   }, 100);
}

運行此命令時,將收到兩個警報,每個警報顯示“ 2”,這是循環退出后的“ x”值。

要解決此問題,您需要調用一個函數,該函數將在發生超時時返回要調用的函數:

function create_alerter(z) {
    return function() {
        alert("fixed: " + z);
    }
}

for (x = 0; x < 2; x++) {
    setTimeout(create_alerter(x), 100);
}

如果您不喜歡為此使用單獨的函數,則可以定義函數返回函數並內聯調用:

for (x = 0; x < 2; x++) {
    setTimeout(function(z) {
       return function() {
          alert(z);
       }
    }(x), 100);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM