351

現在実行中の JavaScript をロードしたスクリプト要素を参照するにはどうすればよいですか?

これが状況です。ページの上部にロードされている「マスター」スクリプトがあり、最初に HEAD タグの下にあります。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript" src="scripts.js"></script>

「scripts.js」には、他のスクリプトをオンデマンドでロードできるようにする必要があるスクリプトがあります。HEAD 要素のレンダリングが完了していないため、HEAD タグを参照せずに新しいスクリプトを追加する必要があるため、通常の方法ではうまくいきません。

document.getElementsByTagName('head')[0].appendChild(v);

私がやりたいことは、現在のスクリプトをロードしたスクリプト要素を参照して、動的にロードされた新しいスクリプト タグをその後に DOM に追加できるようにすることです。

<script type="text/javascript" src="scripts.js"></script>
loaded by scripts.js--><script type="text/javascript" src="new_script1.js"></script>
loaded by scripts.js --><script type="text/javascript" src="new_script2.js"></script>
4

14 に答える 14

764

現在のスクリプト要素を取得する方法:

1.使用document.currentScript

document.currentScript<script>スクリプトが現在処理されている要素を返します。

<script>
var me = document.currentScript;
</script>

利点

  • シンプルかつ明示的。信頼性のある。
  • スクリプトタグを変更する必要はありません
  • 非同期スクリプト ( defer& async)で動作
  • 動的に挿入されたスクリプトに対応

問題

  • 古いブラウザや IE では動作しません。
  • モジュールでは動作しません<script type="module">

2. ID でスクリプトを選択

スクリプトに id 属性を与えると、 を使用して id で簡単に選択できますdocument.getElementById()

<script id="myscript">
var me = document.getElementById('myscript');
</script>

利点

  • シンプルかつ明示的。信頼性のある。
  • ほぼ全面的にサポート
  • 非同期スクリプト ( defer& async)で動作
  • 動的に挿入されたスクリプトに対応

問題

  • script タグにカスタム属性を追加する必要があります
  • id属性は、一部のブラウザーで一部のエッジ ケースのスクリプトに奇妙な動作を引き起こす可能性があります。

3.data-*属性を使用してスクリプトを選択します

スクリプトに属性を与えると、スクリプトdata-*内から簡単に選択できるようになります。

<script data-name="myscript">
var me = document.querySelector('script[data-name="myscript"]');
</script>

これには、前のオプションよりも利点がほとんどありません。

利点

  • シンプルかつ明示的。
  • 非同期スクリプト ( defer& async)で動作
  • 動的に挿入されたスクリプトに対応

問題

  • script タグにカスタム属性を追加する必要があります
  • HTML5、およびquerySelector()すべてのブラウザで準拠していない
  • id属性を使用するよりも広くサポートされていません
  • エッジケースを回避<script>します。id
  • ページ上で別の要素が同じデータ属性と値を持つ場合、混乱する可能性があります。

4. src でスクリプトを選択します

データ属性を使用する代わりに、セレクターを使用してソースごとにスクリプトを選択できます。

<script src="//example.com/embed.js"></script>

埋め込み.js で:

var me = document.querySelector('script[src="//example.com/embed.js"]');

利点

  • 信頼性のある
  • 非同期スクリプト ( defer& async)で動作
  • 動的に挿入されたスクリプトに対応
  • カスタム属性や ID は不要

問題

  • ローカル スクリプトでは機能しませ
  • 開発や本番など、さまざまな環境で問題が発生します
  • 静的で壊れやすい。スクリプト ファイルの場所を変更するには、スクリプトを変更する必要があります。
  • id属性を使用するよりも広くサポートされていません
  • 同じスクリプトを 2 回ロードすると問題が発生します

5.すべてのスクリプトをループして、必要なスクリプトを見つけます

すべてのスクリプト要素をループして、それぞれを個別にチェックして、必要なものを選択することもできます。

<script>
var me = null;
var scripts = document.getElementsByTagName("script")
for (var i = 0; i < scripts.length; ++i) {
    if( isMe(scripts[i])){
      me = scripts[i];
    }
}
</script>

querySelector()これにより、属性をうまくサポートしていない古いブラウザーで以前の両方の手法を使用できます。例えば:

function isMe(scriptElem){
    return scriptElem.getAttribute('src') === "//example.com/embed.js";
}

これは、採用されたアプローチの利点と問題を継承しますが、依存しないquerySelector()ため、古いブラウザーでも機能します。

6.最後に実行されたスクリプトを取得する

スクリプトは順番に実行されるため、最後のスクリプト要素が現在実行中のスクリプトになることがよくあります。

<script>
var scripts = document.getElementsByTagName( 'script' );
var me = scripts[ scripts.length - 1 ];
</script>

利点

  • 単純。
  • ほぼ全面的にサポート
  • カスタム属性や ID は不要

問題

  • 非同期スクリプト ( & ) では機能しませdeferasync
  • 動的に挿入されたスクリプトでは機能しませ
于 2014-03-30T15:02:49.060 に答える
90

スクリプトは順番に実行されるため、現在実行されているスクリプト タグは、それまでページの最後のスクリプト タグになります。したがって、script タグを取得するには、次のようにします。

var scripts = document.getElementsByTagName( 'script' );
var thisScriptTag = scripts[ scripts.length - 1 ];
于 2010-07-24T19:29:04.380 に答える
14

idおそらく最も簡単な方法は、scrip タグに属性を与えることです。

于 2008-12-31T20:29:42.110 に答える
12

スクリプトは、"defer" または "async" 属性がない場合にのみ順次実行されます。スクリプト タグの可能な ID/SRC/TITLE 属性の 1 つを知っていると、このような場合にも機能する可能性があります。したがって、Greg と Justin の両方の提案は正しいです。

document.currentScriptWHATWG リストには既に の提案があります。

編集: Firefox > 4 は既にこの非常に便利なプロパティを実装していますが、最後に確認した IE11 では利用できず、Chrome 29 と Safari 8 でのみ利用できます。

編集:「document.scripts」コレクションについては誰も言及していませんが、現在実行中のスクリプトを取得するためのクロスブラウザーの代替手段として、次のものが適していると思います。

var me = document.scripts[document.scripts.length -1];
于 2010-09-12T16:56:02.407 に答える
8

ページの読み込み時と、javascript (例: ajax) でスクリプト タグが追加されたときに機能する必要があります。

<script id="currentScript">
var $this = document.getElementById("currentScript");
$this.setAttribute("id","");
//...
</script>
于 2011-10-18T00:59:01.503 に答える
4

次の簡単な手順に従って、現在実行中のスクリプト ブロックへの参照を取得します。

  1. スクリプト ブロック内にランダムな一意の文字列を配置します (スクリプト ブロックごとに一意/異なる必要があります)。
  2. document.getElementsByTagName('script') の結果を反復し、それぞれのコンテンツ (innerText/textContent プロパティから取得) から一意の文字列を探します。

例 (ABCDE345678 は一意の ID) :

<script type="text/javascript">
var A=document.getElementsByTagName('script'),i=count(A),thi$;
for(;i;thi$=A[--i])
  if((thi$.innerText||thi$.textContent).indexOf('ABCDE345678'))break;
// Now thi$ is refer to current script block
</script>

ところで、あなたの場合、昔ながらの document.write() メソッドを使用して別のスクリプトを含めることができます。DOM はまだレンダリングされていないと述べたように、ブラウザは常に線形シーケンスでスクリプトを実行するという事実を利用できます (後でレンダリングされる遅延スクリプトを除く)。そのため、ドキュメントの残りの部分はまだ「存在しません」。document.write() で作成したものはすべて、呼び出し元スクリプトの直後に配置されます。

元の HTML ページの例:

<!doctype html>
<html><head>
<script src="script.js"></script>
<script src="otherscript.js"></script>
<body>anything</body></html>

script.js の内容:

document.write('<script src="inserted.js"></script>');

レンダリング後、DOM 構造は次のようになります。

HEAD
  SCRIPT script.js
  SCRIPT inserted.js
  SCRIPT otherscript.js
BODY
于 2012-02-26T07:44:44.427 に答える
4

非同期および遅延スクリプトを処理するためのアプローチは、オンロード ハンドラーを活用することです。すべてのスクリプト タグに対してオンロード ハンドラーを設定し、最初に実行するものを自分のものにする必要があります。

function getCurrentScript(callback) {
  if (document.currentScript) {
    callback(document.currentScript);
    return;
  }
  var scripts = document.scripts;
  function onLoad() {
    for (var i = 0; i < scripts.length; ++i) {
      scripts[i].removeEventListener('load', onLoad, false);
    }
    callback(event.target);
  }
  for (var i = 0; i < scripts.length; ++i) {
    scripts[i].addEventListener('load', onLoad, false);
  }
}

getCurrentScript(function(currentScript) {
  window.console.log(currentScript.src);
});
于 2013-08-06T21:32:13.023 に答える
1

FF3、IE6、および 7 で動作するこれを入手しました。オンデマンドでロードされたスクリプトのメソッドは、ページのロードが完了するまで使用できませんが、それでも非常に便利です。

//handle on-demand loading of javascripts
makescript = function(url){
    var v = document.createElement('script');
    v.src=url;
    v.type='text/javascript';

    //insertAfter. Get last <script> tag in DOM
    d=document.getElementsByTagName('script')[(document.getElementsByTagName('script').length-1)];
    d.parentNode.insertBefore( v, d.nextSibling );
}
于 2008-12-31T21:12:16.627 に答える
0

スクリプトのファイル名を推測できる場合は、それを見つけることができます。これまでのところ、Firefox で次の機能を実際にテストしただけです。

  function findMe(tag, attr, file) {
    var tags = document.getElementsByTagName(tag);
    var r = new RegExp(file + '$');
    for (var i = 0;i < tags.length;i++) {
      if (r.exec(tags[i][attr])) {
        return tags[i][attr];
      }
    }
  };
  var element = findMe('script', 'src', 'scripts.js');
于 2009-11-11T02:05:20.970 に答える