web-dev-qa-db-ja.com

動的に作成されたスクリプトタグが実行されたことを知る方法は?

スクリプトタグを動的に作成しています:

var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.charset = 'utf-8';
script.defer = true;
script.async = true;
script.text = 'some my javascript content here';
head.appendChild(script);

script.onload = function () {
    // this never get fired..
    debugger;
}

スクリプトが他のコードブロック内で実行されたときに通知を受け取る方法は?多分いくつかのイベント?

11
Kosmetika

スクリプトにIDを追加し、JSでそのDOM要素に対して手動でloadイベントを発生させることで、これを機能させることができました。 Chromeでのみテストされ、古いIEによると [〜#〜] mdn [〜#〜] )で問題が発生します。

var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.charset = 'utf-8';
script.id = 'testing';
script.defer = true;
script.async = true;
script.onload = function () {
    console.log('The script is loaded');
}
script.text = ["console.log('This is from the script');",
               "var script = document.getElementById('testing');",
               "var event = new UIEvent('load');",
               "script.dispatchEvent(event);"].join('');
head.appendChild(script);

フィドル

9
pherris

最近のブラウザでは、 Mutation Observer を使用して、要素の変更を検出できます–この場合はhead。このようなもの:

observer = new MutationObserver(function (m) {
    // This will be fired
});
observer.observe(document.head, {childList: true});

残念ながら、これはIE <11では機能しませんが、IEではonloadが起動されているようですので、IEで使用できます。

jsFiddleでのライブデモ

2
Teemu

別の解決策(onloadまたはsrcを使用しない)

window.onload = function(){

    var script = document.createElement('SCRIPT'),
        content = 'console.debug("Hello Kitty");'; // or console.log

    script.type = 'text/javascript';

    try {
      script.appendChild(document.createTextNode(content));
    } catch (e) {
      script.text = content;
    } finally {
      document.getElementsByTagName("HEAD")[0].appendChild(script);
    }
};

作業デモ (IE、FF、ChromeおよびOperaでテスト済み)

0
hex494D49

スクリプトソースを設定する前に、onload関数を定義する必要があります。ただし、Teemuが私に言ったように、textプロパティを介してJavaScriptを記述しているため、onloadイベントは発生しません。最善のオプションは、外部jsファイルを用意し、それをsrc属性を介してロードすることです。

順序は次のとおりです。

  • スクリプト要素をDOMに追加します
  • オンロード関数を定義する
  • srcを定義します
_var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.charset = 'utf-8';
script.defer = true;
script.async = true;
head.appendChild(script);
script.onload = function () {
    // this never get fired..
    debugger;
}
script.src = 'scriptName.js';
_

次に、onloadイベントが発生し、console.log("script has loaded!");ステートメントを関数に挿入できます。

0
Sterling Archer

コードは、スクリプトがDOMに追加されたかどうかを100ミリ秒ごとにチェックします。イベントリスナーやディスパッチイベントを必要とせずに、アプリ全体のどこでも使用できます。同様に、設定した時間間隔でスクリプトが追加されない場合にコードがエラーをスローする時間間隔を確認できます。

const waitForScriptToLoad = (scriptName, checkTimeMs, timeOutMs) => {
  let elapsedTime = 0;
  return new Promise((resolve, reject) => {
    setTimeout(x => reject('script: ' + scriptName + ' Timed out!')
      , timeOutMs)
    const time = setInterval(() => {
      elapsedTime += checkTimeMs;
      if (document.body.innerHTML.indexOf(scriptName) > -1) {
        resolve(
          {
            response: 'script: ' + scriptName + ' found!',
            time: (elapsedTime / 1000).toFixed(2) + 's'
          });
        clearInterval(time);
      }
    }, checkTimeMs)
  })
}

waitForScriptToLoad('script_name.js', 100, 20000)
  .then(res => console.log(res))
  .catch(err => console.log(err))
0
Eugen Sunic

コードを.jsファイルに抽出します。

スクリプトに_script.src = 'yourjs.js';_を追加します。

スクリプトがDOMに追加されると、.jsファイルが没入型で実行されます。

_yourjs.js_の上にif(console){console.debug('helloworld.');}を追加すると、メッセージが表示されます。

0
Peter Rader