Как я могу ждать, пока <script>добавится в тело к выполнению финала sh - PullRequest
1 голос
/ 20 апреля 2020

Когда пользователь нажимает кнопку, мне нужно добавить к своему телу внешний скрипт. Это требование.

Грач ie вопрос. Допустим, внешняя библиотека создает переменную window.newLib. Как я могу получить уведомление, когда переменная newLib готова для использования?

Я пробовал это, но onload не вызывается:

  const script = document.createElement('script');
  script.innerHTML = 'window.test = 1; console.log("test defined.");';
  script.onload = "console.log('onload called.', window.test)"
  script.async = false;
  document.body.appendChild(script);

Это работает, но мне кажется, что это грязно. Есть ли лучший способ?

const injectScript = () => {
  const script = document.createElement('script');
  script.innerHTML = 'setTimeout(() => {window.test = 1},10500); console.log("test defined.");';
  script.async = false;
  document.body.appendChild(script);
}

const nap = ms => new Promise(res => setTimeout(res, ms));

const maxAttempts = 100;
const msNap = 100; // 10s timeout

const start = async () => {
  injectScript();
  let id = 0;
  while (true) {
    if (++id === maxAttempts) {
      throw(`Lib took too long to load: ${id * msNap}ms`);
    }
    if (window.test) break;
    await nap(msNap);
  }
  console.log('External lib correctly loaded.');
};
start();

Ответы [ 2 ]

1 голос
/ 20 апреля 2020

Благодаря @Ultimater. Кажется, это работает как ожидалось:

const script = document.createElement('script');
script.src = 'data:text/html,id = 0;while(true){ if(++id==1000000) break;} window.test = 1; console.log("test defined.");';
script.onload = () => console.log('onload called.', window.test);
document.body.appendChild(script);
0 голосов
/ 20 апреля 2020

Попробуйте это:

const injectScript = () => {
        const script = document.createElement('script');
        script.innerHTML = 'console.log("Function loaded..."); window.postMessage({cmd:"loaded"});';
        script.async = false;
        document.body.appendChild(script);
        }

        setTimeout(injectScript, 3000);

        window.addEventListener('message', function(e){
            if(e.data.cmd === 'loaded'){
                console.log('external library loaded');
            }
        });
...