JavaScriptのパスを取得

Webブラウザに読み込まれたJavaScriptのファイルが、自分自身のパスを知りたいことがあります。その際に、パスを取得するための関数です。 2018-06-29

 JavaScriptと画像などを、まとめて同じディレクトリに入れて配布することは、よくあります。そうした時に、HTMLファイル直下でないなど、任意のディレクトリに配置された場合、画像などのパスが分からなくなるという問題があります。

 そうした時に、自身のパスを取得して、同じディレクトリにある画像などを読み込みにいければ便利です。そうした処理を行うための関数です。

 「searchJSPath('jquery.min.js')」のようにすると、「["https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/", "jquery.min.js"]」のように、ディレクトリとファイル名を分割した配列を戻します。

 「const p = searchJSPath('myLib.js');」としたあと、「const pImg = p[0] + 'myImg.png';」のように、パスを作ることができます。

 ファイル構成は以下の通りです。>>ダウンロード

※ 初期化用関数「init」の処理については「Webブラウザ/Node.js 互換関数」をご覧下さい。Node.js用の処理は、今回のコードにはありません。

サンプル動作

sample/searchJSPath.js

'use strict';

(function() {
	const _t = init('com.crocro.util');

	// searchJSPath | 日付時間フォーマット
	_t.searchJSPath = function(fnm) {
		// 変数の初期化
		let res = ['', fnm];
		const re = new RegExp('(^|^.*\/)' + fnm.replace(/\./g, '\\.') + '$');

		// scriptタグを探索
		const scriptArr = document.getElementsByTagName('script');
		for (let i = 0; i < scriptArr.length; i ++) {
			// src部分を取得
			let src = scriptArr[i].src;

			// キャッシュ排除用の「?20XX-XX-XX」のような
			// パラメータを除去
			src = src.replace(/\?.+$/, "");

			// 一致した場合は、パスの一部を取得
			const mtch = src.match(re);
			if (mtch) {res[0] = mtch[1]}
		};

		return res;
	};

	// 初期化用関数
	function init(p) {
		return ((o, p) => {
			p.split('.').forEach(k => o = o[k]||(o[k]={}));
			return o})(window, p);
	};
})();

解説

 「document.getElementsByTagName('script');」で、「script」タグの「HTMLCollection」を得ます。

 この「HTMLCollection」は、配列のように「length」を持ちますが、「forEach」などのメソッドは使えません。そのため、for文を使って、各要素を処理しています。

 「let src = scriptArr[i].src;」として、「script」タグの「src」属性の値を得て、「?」以下(キャッシュ排除用に「?20XX-XX-XX」のようなパラメータを付けたりする)を削除しています。

 そして、パスの末尾にファイル名があれば、そのディレクトリまでの部分を取得しています。

searchJSPath|JavaScriptのパスを取得

引数に指定したファイル名のJavaScriptのパスを探して、ディレクトリまでのパスと、ファイル名の配列にして戻します。

@param {String} fnm - ファイル名。
JavaScriptのファイル名を指定します。

@return 「['ディレクトリまでのパス', 'ファイル名']」の配列。

サンプル

const searchJSPath = com.crocro.util.searchJSPath;
console.log(JSON.stringify(searchJSPath('jquery.min.js')));
// '["https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/","jquery.min.js"]'

sample/index.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>JavaScriptのパスを取得 - JavaScript実用サンプルコード解説付き</title>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
    </script>

    <script src="searchJSPath.js"></script>
    <script src="main.js"></script>
    <link rel="stylesheet" href="main.css">
  </head>
  <body>
    <textarea id="src"></textarea>
    <button id="exec">実行</button>
    <textarea id="dst"></textarea>
  </body>
</html>

sample/main.js

'use strict';

$(function() {
	// 変数の初期化
	const $src  = $('#src');
	const $dst  = $('#dst');
	const $exec = $('#exec');

	// 値のセット
	$src.val(String.raw`
const searchJSPath = com.crocro.util.searchJSPath;
console.log(JSON.stringify(searchJSPath('searchJSPath.js')));
console.log(JSON.stringify(searchJSPath('jquery.min.js')));
	`.trim());

	// コンソール ログのラップ
	const log = console.log;
	console.log = function() {
		for (let i = 0; i < arguments.length; i ++) {
			$dst.append(arguments[i] + ' ');
		}
		$dst.append('\n');
		log.apply(console, arguments);
	};

	// クリック時の処理
	$exec.click(() => {
		$dst.empty();
		eval($src.val());
	});
});

sample/main.css

html,
body {
	margin: 0;
	padding: 0;
}

textarea,
button {
	box-sizing: border-box;
	width: 100%;
	vertical-align:bottom;
}
textarea {
	height: 5em;
}

紹介

Steamでゲームをリリースした時の経験をマニュアル的にまとめた本です。
8bit風RTS「TinyWar」のアルゴリズムを、コード付きで解説した本です。
JavaScriptから手軽に扱える形態素解析器『kuromoji.js』を使い、日本語を分解して遊ぶ本です。
node.jsを使い、「Google Chrome」のユーザーデータを、自動処理でメンテナンスするプログラムを開発する本です。
HTML5でローカルアプリが作れるNW.jsで、同人ゲームを作るための基礎知識の本です。
シミュレーションRPG「TinySRPG」のアルゴリズムを、コード付きで解説した本です。
JavaScriptの実行時エラーを分類して、ワンライナーのソースコードとエラーメッセージを収録した本です。
禁止文字つきコードゴルフを1年以上出題して、その解答ノウハウをまとめた本です。
2011年の春ごろに、Javaで「NyARToolKit」互換のARマーカー認識プログラムを書いた時のレポートです。