繁体   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