現在実行中の 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>
ベストアンサー1
現在のスクリプト要素を取得する方法:
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
) - 動的に挿入されたスクリプトで動作します
問題点
- スクリプトタグにカスタム属性を追加する必要があります
id
特定のケースでは、一部のブラウザでスクリプトに奇妙な動作を引き起こす可能性があります。
data-*
3.属性を使用してスクリプトを選択する
スクリプトにdata-*
属性を使用すると、内部から簡単に選択できます。
<script data-name="myscript">
var me = document.querySelector('script[data-name="myscript"]');
</script>
これには、前のオプションに比べて利点がほとんどありません。
利点
- シンプルで明確。
- 非同期スクリプトで動作します (
defer
&async
) - 動的に挿入されたスクリプトで動作します
問題点
- スクリプトタグにカスタム属性を追加する必要があります
- HTML5であり、
querySelector()
すべてのブラウザで対応しているわけではない id
属性を使用するよりも広くサポートされていない- エッジケース
<script>
を回避します。id
- ページ上の別の要素に同じデータ属性と値がある場合、混乱する可能性があります。
4. srcでスクリプトを選択する
データ属性を使用する代わりに、セレクターを使用してソース別にスクリプトを選択できます。
<script src="//example.com/embed.js"></script>
embed.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は必要ありません
問題点
- 非同期スクリプトでは動作しません
defer
( &async
) - 動的に挿入されたスクリプトでは動作しません