特定のページのときのみ外部JavaScriptファイルをJavaScriptファイルから読み込む

特定のページでのみ外部JavaScriptフィイルを読み込ませたい、 と言う要請は、 WordPressなどではfunctions.phpを用いて実装するのは最早お馴染みの手法である様に、 割と頻繁に受けるものです。

稼働中システムの追加要請

処が諸事情に因り、例えば企業などでは一旦導入したシステムは使い続けるのが通常ですから、 往往にして融通の効かない古い独自のCMS上で此れを実現しなければならない場面があります。 具体的には各々ページに読み込みファイルが書き込んであって、一括管理できない、 と言う形式の上ではなかなか実装が難儀だったりする訳です。 その様なCMSのシステム上でソースを読んで一括管理できそうなファイルを見付けて、 例えばPHPに於いては $_SERVER など環境変数で場合分けしようとしても ヘッダー部分にのみ反映されるファイルだったりすることもあるでしょう。

手元の事例では幾ら新規に必要な外部JavaScriptファイルの読み込みに成功しても、 機能しないのに首を捻って、更に突っ込んで見てみると、 其のJavaScriptファイルはjQueryを必要としているのに、 当のjQueryファイルがフッター部分での読み込みになっていたりします。 必要なjQueryが読み込まれていないのですから機能する筈もありません。 しかもそのjQueryファイルを読み込むのは各ファイルにインクルードの旨、直書きされる、拡張子 .html のHTMLファイルで .htaccess を書き換えて拡張子の制限を広げたりするのも要らぬオーバーヘッドが発生しそうですし、 全読み込み元ファイルをPHPファイルなどにするのも工数が嵩みますし、 成る可くなら他に影響を与えたくないための当初取ろうとした手法であれば、本末転倒です。 するとフッターファイル内で場合分け操作ができない状況も鑑みねばなりません。

スポンサーリンク

JavaScriptの要請される2技術

元ファイルに書き込んでも影響せず目論見が達成できるとなると、 使える手法が限られて来ますので考える迄もありません。 JavaScriptファイルからJavaScriptファイルを読み込ませる手法です。 JavaScriptファイルなら静的HTMLファイルに問題なく書き込め動的な処理が可能となるからです。 手元の改変すべき環境では都合の宜しいことに インクルードフッターファイルの最後にページで必要な一連のJavaScript処理をまとめた 外部JavaScriptファイルが読み込まれていました。 勿論、当然ながらjQueryファイル読み込みの後の行です。

方針は決定しました。 目論見を達成するに必須のJavaScript技術は以下の二種類となるでしょう。

  • 特定のURLのみで機能すること
  • 外部JavaScriptファイルをJavaScriptから読み込むこと

最初の試行

先ずは前者の情報を欲してネットを繰れば 以下リンクを貼る先のページに行き当たりました。 サイト ときどきWEB から2013年の2月7日に配信された情報にて、 次に箇条書きする二つのケースに於いての事例が示されています。

『jQueryで特定のURLが一致したら処理してやんよ!!!』

  • 指定のURLが一致した場合の追加処理
  • 特定文字列が入ったURLに一致した場合

此れを参考に書いたJavaScriptコードが以下です。 後者の事例を参考にしたもので、 オンラインの当該アドレスで test、とダイアログ表示させ要望の機能を確認しました。

$(window).bind("load", function(){
	if(document.URL.match(/hoge/)) {
		alert("test");
	}
});

では次に、 JavaScript内から外部JavaScriptファイル読み込む方法です。 此れは一般的に document.write が用いられ勝ちな気がしています。 事例を示せば以下の如くなるでしょう。

document.write("<script type='text/javascript' src='huga.js'></script>");

以下、リンクを貼る2016年7月13日の teratail にも前提として質問と回答の遣り取りが為されています。

JavaScript - javascriptファイル内で外部javascriptを読み込む方法について(41023)

但し、この一般的にしばしば用いられる手法には問題が有る様で、 手元の環境でもHTMLのアウトプットが以下の様な感じとなって、 人に見えるブラウザ画面は真っ白になってしまいました。

<html>
	<head>
		<script type="text/javascript" src="fuga.js"></script>
	</head>
</html>

次なる試行

事前のURL場合分けに問題が有るのかと書式を変えても改善されませんから、 どうやら問題は外部JavaScriptファイルの読み込み手法にある道理で、 従って異なる手法を試すべくネットを繰って見付けたのが、以下の Tips of Rubbish から2016年9月2日に配信された情報です。

javascriptで外部scriptの読み込み方法の検討

此処には先に述べた document.write の問題点も述べられています。 以下に引用しましょう。

非常に簡単に実装する方法はこの「document.write」であるワケだが、この関数には致命的な欠点が存在する。
僕が以前かいた会社のブログで詳細を見てもらいたいのだが、
document.writeがイベントタイミングによって挙動が違う
ようするに、読み込まれたJSでそのまま記述する分には問題ないのだが、settimeoutや、別イベントを待って処理するような事をした場合に、画面真っ白問題が発生するのである。

手元の環境で発現したのは正しく此の問題でした。

更には、GoogleやYahooなどで利用されるタグマネージャー機能との相性が悪い問題も挙げられています。 どうやら避けるに如くはないようです。 するとどのようにして外部JavaScriptファイルをJavaScript内から読み込むのか、 と言う問題が残りますが、当然ながら当該ページでは其の情報がメインとなっており、 以下、二手法が挙げられています。

  • createElement -> appendChild 方式
  • ajax -> eval 方式

実稼働コード

今回は特に非同期処理は必要ありませんので前者の createElement -> appendChild 方式を採用しました。 以てURL場合分けのコードのアラートの部分に外部JavaScript読み込み処理を記述して、 目論見の実現を試みたコードが以下となります。

$(window).bind("load", function(){
	if(document.URL.match(/hoge/)) {
		// document.write("<script type='text/javascript' src='fuga.js'></script>");
		var s = document.createElement("script");
		s.type = "text/javascript";
		s.src = "fuga.js";
		// s.onload = function(){ alert("読み込み確認") };
		document.body.appendChild(s);
	}
});

赤字のコメントアウト部分ですが、 前者が document.write 方式で画面が真っ白になってしまうコードで、 後者はコメントアウトを外せば「読み込み確認」とダイアログ表示され オンラインでの機能が確認出来るコードです。 此の最終コードにて目論見の機能は首尾良くオンライン上で発現して欲しいアドレスでのみ発現してくれました。