Не может включать более одного файла JS. Событие Onload запускается только для последнего файла, но столько раз, сколько у меня есть файлы. Как это решить?
Я хочу добавить несколько 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'
определение. Оповещение срабатывает дважды и показывает код 'two'
, А у меня только функция 'two'
я моя собственность 'two'
, последний, который я передал с параметром. И файлы добавляются в DOM просто файл.
Я пытался создать <script>
тег вне for/in
цикл, и даже создал массив и сохранил каждый из двух сценариев как отдельные элементы этого массива, но это тоже не помогает - только последний файл находится в onload
и дважды.
В чем проблема? Почему это не работает для двух файлов? Возможно ли это решить?
1 ответ
Трудно сказать, когда вы не включаете полный код, но, скорее всего, вы столкнулись с проблемой закрытия.
Ваша функция onload определена внутри цикла for, что означает, что она будет привязывать ссылку к локальной переменной "key". К тому моменту, когда функция "unload" действительно запустится, цикл for будет завершен, и "key" будет "two", так что вы увидите "two" в обоих оповещениях.
Вот более тривиальный пример той же проблемы:
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);
}
Если вам не нравится иметь отдельную функцию для этого, вы можете определить функцию, возвращающую функцию, и вызывать ее inline:
for (x = 0; x < 2; x++) {
setTimeout(function(z) {
return function() {
alert(z);
}
}(x), 100);
}