Javascript загружает внешний скрипт при создании HTMLElement

#javascript #html

Вопрос:

у меня проблема, когда я пытаюсь загрузить внешний js и запустить функцию внутри, как только будет создан тег сценария. В myFile.js код у меня есть этот код :

 function loadMyScript() {
return new Promise(function (resolve, reject) {
var s;
s = document.createElement("script");
s.defer = true;
s.id = "test";
s.src =
  "myUrl/externalfile.min.js";
s.onload = resolve;
s.onerror = reject;
document.head.appendChild(s);
 });
}
 

В том же файле я пытаюсь вызвать loadMyScript,
и я хотел бы, чтобы новый объект был создан из кода моего внешнего js :myUrl/externalfile.min.js

 async function testMethod(button, objet) {
    //new myObjet(button, objet) will be called in myUrl/externalfile.min.js
    return this.loadMyScript().then(() => {
       console.log('Buildin MyObject');
       return new MyObjet(button, objet);
    });
}
 

в моем сгенерированном html я вижу это.
Здесь мой метод loadMyScript правильно создает html-элемент в :

       <script defer="" id="test" src="myUrl/externalfile.min.js"></script>
 

Проблема в том, что код, который я написал .затем (…), похоже, не выполняется = > >Мой объект не создан.

В то время как, когда я вставляю строку <скрипт><скрипт> вручную в заголовок html, все, кажется, работает правильно

Есть какие-нибудь советы?

Ответ №1:

Насколько я понимаю, вы хотите динамически загружать JavaScript из внешнего файла и вызывать функцию этого файла непосредственно после этого.

Почему бы вам не использовать import() для этого? Вместо добавления тега сценария в DOM вы объявляете свой файл JS просто как модуль и вызываете его внутри текущего файла JS с помощью import() функции. Он поддерживается всеми основными браузерами.

  1. Файл для импорта (например module.js)
 export function hello() {
  return "Hello, from Module.js";
}
 
  1. Ваш основной файл (например index.js)
 import("./path/to/module.js")
.then((module) => {
    console.log(
       module.hello()
    );
    // Do something with the module.
  });
 

Вы можете прочитать немного больше на странице MDN для импорта.

Комментарии:

1. У нас нет внешней библиотеки, есть ли другой способ ? Спасибо

Ответ №2:

Использование onload и onerror , как правило, больше не считается «лучшей практикой» — вместо этого вы можете прикрепить прослушиватели событий к созданному вами элементу:

 function loadMyScript() {
  return new Promise(function(resolve, reject) {
    var s = document.createElement("script");
    s.defer = true;
    s.id = "test";
    s.src = "myUrl/externalfile.min.js";
    s.addEventListener('load', () => resolve(s), false);
    s.addEventListener('error', () => reject(s), false);
    document.head.appendChild(s);
  });
}
 

Комментарии:

1. Спасибо, но я не думаю, что это изменит результат, не так ли ?

2. @узо, почему бы и нет…? Ты пробовал это сделать? Каков был результат?

3. во-первых, спасибо вам за вашу помощь, я пытался, но это ничего не изменило

Ответ №3:

Всякий раз , когда вы запускаете testMethod , вы фактически возвращаете a Promise , что означает, что вы должны использовать .then его (или await если ваша функция асинхронна).

Взгляните на этот пример, где загружается внешний скрипт с именем js.js :

  • Примечание: для того, чтобы это сработало, вам необходимо иметь файл js.js в той же папке, что и этот фрагмент (после сохранения на вашем локальном компьютере).
 function loadMyScript() {
    return new Promise(function (resolve, reject) {
        let s = document.createElement("script");
        s.src = "js.js";
        s.onload = resolve;
        s.onerror = reject;
        document.head.appendChild(s);
    });
};

async function testMethod() {
    return loadMyScript().then(() => func(50), (e) => console.log("Error:", e));
};

function RUN_THIS() {
    testMethod().then(res => {
        if(!res) return;
        alert("Loaded script, executed function. The external function returned: "   res);
    });
}; 

Чтобы сделать код более читабельным, я использовал await приведенные ниже:

 function loadMyScript() {
    return new Promise(function (resolve, reject) {
        let s = document.createElement("script");
        s.onload = resolve;
        s.onerror = reject;
        s.src = "js.js";
        document.head.appendChild(s);
    });
};

async function testMethod() {
    const result = await loadMyScript();
    // Now perform checks using "result";
    return func(50);
};

async function RUN_THIS() {
    const result = await testMethod()
    if(!result) return false;
    console.log("Loaded script, executed function. The external function returned:", result);
}; 

Здесь func указана функция или метод, которые определены во внешнем скрипте, который вы пытаетесь загрузить.

Комментарии:

1. можете ли вы объяснить значение функции ?

2. @ouzo Да, извините, я забыл упомянуть, что func это функция или метод, которые определены во внешнем скрипте. 50 это просто случайный аргумент, который я передал просто в качестве примера.