他のJavaScriptファイルの中にJavaScriptファイルを含めることを可能にするCSSの@import
のようなJavaScriptの何かがありますか?
JavaScriptの旧バージョンにはインポート、インクルード、または必要性がなかったため、この問題に対するさまざまなアプローチが開発されています。
しかし2015年(ES6)以来、JavaScriptはNode.jsにモジュールをインポートするための ES6モジュール 標準を持っています。これは 最近のブラウザー でもサポートされています。
古いブラウザとの互換性のために、 build および/または transpilation ツールを使用できます。
ECMAScript(ES6)モジュールは、v8.5からNode.jsで--experimental-modules
フラグ付きでサポートされています。関係するすべてのファイルは.mjs
拡張子を持つ必要があります。
// module.mjs
export function hello() {
return "Hello";
}
// main.mjs
import { hello } from 'module'; // or './module'
let val = hello(); // val is "Hello";
ブラウザはECMAScriptモジュールを直接ロードすることをサポートしています(Webpackのようなツールは必要ありません) 以降 Safari 10.1、Chrome 61、Firefox 60、およびEdge 16。現在のサポートを確認する caniuse 。
<script type="module">
import { hello } from './hello.mjs';
hello('world');
</script>
// hello.mjs
export function hello(text) {
const div = document.createElement('div');
div.textContent = `Hello ${text}`;
document.body.appendChild(div);
}
詳しくは https://jakearchibald.com/2017/es-modules-in-browsers/ をご覧ください。
動的インポートにより、スクリプトは必要に応じて他のスクリプトをロードできます。
<script type="module">
import('hello.mjs').then(module => {
module.hello('world');
});
</script>
詳しくは https://developers.google.com/web/updates/2017/11/dynamic-import をご覧ください。
Node.jsでもまだ広く使用されているモジュールのインポートの古いスタイルは、 module.exports/require システムです。
// mymodule.js
module.exports = {
hello: function() {
return "Hello";
}
}
// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is "Hello"
JavaScriptが外部のJavaScriptコンテンツをブラウザに含める前処理を必要としない他の方法があります。
AJAX呼び出しで追加のスクリプトをロードし、それを実行するためにeval
を使用することができます。これは最も簡単な方法ですが、JavaScriptサンドボックスセキュリティモデルのため、ドメインに限定されています。 eval
を使用すると、バグ、ハック、セキュリティ問題への扉も開かれます。
動的インポートと同様に、 Fetch Inject ライブラリを使用してスクリプト依存関係の実行順序を制御するためにpromiseを使用してfetch
呼び出しで1つまたは複数のスクリプトをロードできます。
fetchInject([
'https://cdn.jsdelivr.net/momentjs/2.17.1/moment.min.js'
]).then(() => {
console.log(`Finish in less than ${moment().endOf('year').fromNow(true)}`)
})
jQuery ライブラリはロード機能を提供します 1行で :
$.getScript("my_lovely_script.js", function() {
alert("Script loaded but not necessarily executed.");
});
スクリプトURLを含むスクリプトタグをHTMLに追加できます。 jQueryのオーバーヘッドを回避するために、これは理想的な解決策です。
スクリプトは別のサーバーに配置することもできます。さらに、ブラウザはコードを評価します。 <script>
タグは、Webページの<head>
に挿入することも、閉じる</body>
タグの直前に挿入することもできます。
これがどのように機能するかの例を示します。
function dynamicallyLoadScript(url) {
var script = document.createElement("script"); // create a script DOM node
script.src = url; // set its src to the provided URL
document.head.appendChild(script); // add it to the end of the head section of the page (could change 'head' to 'body' to add it to the end of the body section instead)
}
この関数は、ページのheadセクションの最後に新しい<script>
タグを追加します。ここで、src
属性は、最初のパラメータとして関数に与えられたURLに設定されます。
これらの解決策は両方とも JavaScriptの狂気:動的スクリプトのロード で説明されています。
今、あなたが知る必要がある大きな問題があります。そうすることは、あなたがリモートでコードをロードすることを意味します。最近のWebブラウザは、パフォーマンスを向上させるためにすべてを非同期にロードするため、ファイルをロードして現在のスクリプトを実行し続けます。 (これはjQueryメソッドと手動の動的スクリプトロードメソッドの両方に当てはまります。)
つまり、これらのトリックを直接使用すると、ロードした後の次の行に新しくロードしたコードを使用できなくなります。ロードしています。
例えば、my_lovely_script.js
にはMySuperObject
が含まれています。
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
var s = new MySuperObject();
Error : MySuperObject is undefined
その後、ヒットしたページをリロードします F5。そしてそれはうまくいきます!混乱しています...
それではどうしますか?
さて、あなたは私があなたに与えたリンクで作者が提案するハックを使うことができます。要約すると、急いでいる人々のために、彼はスクリプトがロードされたときにコールバック関数を実行するためにイベントを使います。そのため、コールバック関数にリモートライブラリを使用してすべてのコードを配置できます。例えば:
function loadScript(url, callback)
{
// Adding the script tag to the head as suggested before
var head = document.head;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = callback;
script.onload = callback;
// Fire the loading
head.appendChild(script);
}
次に、スクリプトが ラムダ関数 にロードされた後に、使用したいコードを作成します。
var myPrettyCode = function() {
// Here, do whatever you want
};
それからあなたはすべてを実行します:
loadScript("my_lovely_script.js", myPrettyCode);
スクリプトは、ブラウザの種類やscript.async = false;
の行が含まれているかどうかによって、DOMのロード後または実行前に実行されることがあります。これについて議論している Javascriptのロード全般に関する素晴らしい記事 があります。
この答えの冒頭で述べたように、多くの開発者は彼らのプロジェクトでParcel、Webpack、またはBabelのようなビルド/変換ツールを使用します。コード分割などを行う.
誰かがもっと高度なものを探しているなら、 RequireJS を試してみてください。依存関係管理、同時実行性の向上、重複の回避(つまり、スクリプトを複数回取得する)などの追加の利点が得られます。
JavaScriptファイルを「モジュール」で記述してから、それらを他のスクリプトの依存関係として参照できます。あるいは、RequireJSを単純な「このスクリプトを入手する」ソリューションとして使用することもできます。
例:
依存関係をモジュールとして定義します。
some-dependency.js
define(['lib/dependency1', 'lib/dependency2'], function (d1, d2) {
//Your actual script goes here.
//The dependent scripts will be fetched if necessary.
return libraryObject; //For example, jQuery object
});
implementation.js は、 some-dependency.js に依存する "メイン" JavaScriptファイルです。
require(['some-dependency'], function(dependency) {
//Your script goes here
//some-dependency.js is fetched.
//Then your script is executed
});
GitHub READMEからの抜粋:
RequireJSは普通のJavaScriptファイルともっと定義されたモジュールをロードします。 Webワーカーを含むブラウザ内での使用に最適化されていますが、RhinoやNodeなどの他のJavaScript環境でも使用できます。これは非同期モジュールAPIを実装しています。
RequireJSはプレーンなスクリプトタグを使ってモジュール/ファイルをロードするので、簡単にデバッグできるようにする必要があります。それは単に既存の JavaScriptファイルをロードするために使用することができるので、 あなたはあなたのJavaScriptファイルを書き直す必要なしにあなたの既存のプロジェクトにそれを追加することができます。
...
実際には、isJavaScriptファイルを読み込む方法notなので、新しく読み込んだファイルを読み込んだ直後に、そのファイルに含まれている関数を使用することができ、すべてのブラウザーで機能すると思います。
ページの<head>
要素でjQuery.append()
を使用する必要があります。
$("head").append('<script type="text/javascript" src="' + script + '"></script>');
ただし、この方法にも問題があります。インポートされたJavaScriptファイルでエラーが発生した場合、 Firebug (およびFirefoxエラーコンソールと Chrome Developer Tools も)が報告しますFirebugを使用してJavaScriptエラーを大幅に追跡する場合、これは大きな問題です(私はそうします)。 Firebugは、何らかの理由で新しくロードされたファイルを単に知らないため、そのファイルでエラーが発生した場合、メインの HTML ファイルで発生したことを報告し、見つけるのに苦労しますエラーの本当の理由を突き止めてください。
ただし、それが問題にならない場合は、このメソッドが機能するはずです。
このメソッドを使用する$。import_js()というjQueryプラグインを実際に作成しました。
(function($)
{
/*
* $.import_js() helper (for JavaScript importing within JavaScript code).
*/
var import_js_imported = [];
$.extend(true,
{
import_js : function(script)
{
var found = false;
for (var i = 0; i < import_js_imported.length; i++)
if (import_js_imported[i] == script) {
found = true;
break;
}
if (found == false) {
$("head").append('<script type="text/javascript" src="' + script + '"></script>');
import_js_imported.Push(script);
}
}
});
})(jQuery);
したがって、JavaScriptをインポートするために必要なことは次のとおりです。
$.import_js('/path_to_project/scripts/somefunctions.js');
例 で、このための簡単なテストも行いました。
メインHTMLにmain.js
ファイルが含まれており、main.js
のスクリプトは$.import_js()
を使用して、この関数を定義するincluded.js
という追加ファイルをインポートします。
function hello()
{
alert("Hello world!");
}
そして、included.js
をインクルードした直後に、hello()
関数が呼び出され、アラートを受け取ります。
(この回答は、e-satisのコメントに対する回答です)。
私の考えでは、もう1つの方法は、<script>
タグを使用するのではなく、同期Ajaxリクエストを作成することです。これは Node.js が扱う方法でもあります。
これがjQueryを使った例です。
function require(script) {
$.ajax({
url: script,
dataType: "script",
async: false, // <-- This is the key
success: function () {
// all good...
},
error: function () {
throw new Error("Could not load script " + script);
}
});
}
通常はインクルードを使用するのと同じように、コードで使用できます。
require("/scripts/subscript.js");
次の行で必要なスクリプトから関数を呼び出せるようにします。
subscript.doSomethingCool();
JavaScriptタグを動的に生成し、それを他のJavaScriptコード内からHTMLドキュメントに追加することは可能です。これにより、ターゲットのJavaScriptファイルがロードされます。
function includeJs(jsFilePath) {
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
}
includeJs("/path/to/some/file.js");
ステートメント import
はECMAScript 6にあります。
構文
import name from "module-name";
import { member } from "module-name";
import { member as alias } from "module-name";
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import name , { member [ , [...] ] } from "module-name";
import "module-name" as name;
多分あなたは私がこのページで見つけたこの機能を使用することができますどのように私はJavaScriptファイルにJavaScriptファイルを含めるのですか?:
function include(filename)
{
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = filename;
script.type = 'text/javascript';
head.appendChild(script)
}
これは 同期 バージョン jQueryなし :です。
function myRequire( url ) {
var ajax = new XMLHttpRequest();
ajax.open( 'GET', url, false ); // <-- the 'false' makes it synchronous
ajax.onreadystatechange = function () {
var script = ajax.response || ajax.responseText;
if (ajax.readyState === 4) {
switch( ajax.status) {
case 200:
eval.apply( window, [script] );
console.log("script loaded: ", url);
break;
default:
console.log("ERROR: script not loaded: ", url);
}
}
};
ajax.send(null);
}
このクロスドメインを機能させるには、サーバーは応答にallow-Origin
ヘッダーを設定する必要があります。
私はちょうどこのJavaScriptコードを書いた( Prototype for _ dom _ 操作を使って):
var require = (function() {
var _required = {};
return (function(url, callback) {
if (typeof url == 'object') {
// We've (hopefully) got an array: time to chain!
if (url.length > 1) {
// Load the nth file as soon as everything up to the
// n-1th one is done.
require(url.slice(0, url.length - 1), function() {
require(url[url.length - 1], callback);
});
} else if (url.length == 1) {
require(url[0], callback);
}
return;
}
if (typeof _required[url] == 'undefined') {
// Haven't loaded this URL yet; gogogo!
_required[url] = [];
var script = new Element('script', {
src: url,
type: 'text/javascript'
});
script.observe('load', function() {
console.log("script " + url + " loaded.");
_required[url].each(function(cb) {
cb.call(); // TODO: does this execute in the right context?
});
_required[url] = true;
});
$$('head')[0].insert(script);
} else if (typeof _required[url] == 'boolean') {
// We already loaded the thing, so go ahead.
if (callback) {
callback.call();
}
return;
}
if (callback) {
_required[url].Push(callback);
}
});
})();
使用法:
<script src="prototype.js"></script>
<script src="require.js"></script>
<script>
require(['foo.js','bar.js'], function () {
/* Use foo.js and bar.js here */
});
</script>
これがFacebookが彼らのいたるところにあるLikeボタンのためにどのようにそれをするかの一般化されたバージョンです:
<script>
var firstScript = document.getElementsByTagName('script')[0],
js = document.createElement('script');
js.src = 'https://cdnjs.cloudflare.com/ajax/libs/Snowstorm/20131208/snowstorm-min.js';
js.onload = function () {
// do stuff with your dynamically loaded script
snowStorm.snowColor = '#99ccff';
};
firstScript.parentNode.insertBefore(js, firstScript);
</script>
それがFacebookのために働くならば、それはあなたのために働くでしょう。
script
やhead
の代わりに最初のbody
要素を探すのは、ブラウザによっては見つからない場合は作成されないためですが、script
要素があることが保証されています - これ。詳しくは http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/ をご覧ください。
純粋なJavaScriptを使用したい場合は、document.write
を使用できます。
document.write('<script src="myscript.js" type="text/javascript"></script>');
JQueryライブラリを使用している場合は、$.getScript
メソッドを使用できます。
$.getScript("another_script.js");
_ php _ を使用してスクリプトを組み立てることもできます。
ファイルmain.js.php
:
<?php
header('Content-type:text/javascript; charset=utf-8');
include_once("foo.js.php");
include_once("bar.js.php");
?>
// Main JavaScript code goes here
ここに示されている解決策のほとんどは動的負荷を意味します。代わりに、依存しているすべてのファイルを単一の出力ファイルにまとめるコンパイラを探していました。 Less / Sass プリプロセッサはCSSの@import
at-ruleを扱います。私はこの種の適当なものを見つけることができなかったので、私は問題を解決する簡単な道具を書きました。
そのため、ここにコンパイラ https://github.com/dsheiko/jsic があります。これは$import("file-path")
を要求されたファイルの内容で安全に置き換えます。これは対応する Grunt プラグインです: https://github.com/dsheiko/grunt-jsic 。
JQueryマスターブランチでは、アトミックソースファイルをintro.js
で始まりouttro.js
で終わる単一のファイルに単純に連結します。ソースコード設計に柔軟性がないため、これは私には適していません。 jsicとどのように連携するのかを調べてください。
src/main.js
var foo = $import("./Form/Input/Tel");
src/Form/Input/Tel.js
function() {
return {
prop: "",
method: function(){}
}
}
これでコンパイラを実行できます。
node jsic.js src/main.js build/mail.js
そして、結合ファイルを入手してください
build/main.js
var foo = function() {
return {
prop: "",
method: function(){}
}
};
JavaScriptファイルをロードする意図が インポートされた/インクルードされたファイルからの関数を使用すること である場合、グローバルオブジェクトを定義し、その関数をオブジェクト項目として設定することもできます。例えば:
A = {};
A.func1 = function() {
console.log("func1");
}
A.func2 = function() {
console.log("func2");
}
A.func1();
A.func2();
HTMLファイルにスクリプトを含める場合は、注意が必要です。順序は以下のようになります。
<head>
<script type="text/javascript" src="global.js"></script>
<script type="text/javascript" src="file1.js"></script>
<script type="text/javascript" src="file2.js"></script>
<script type="text/javascript" src="main.js"></script>
</head>
これはする必要があります:
xhr = new XMLHttpRequest();
xhr.open("GET", "/soap/ajax/11.0/connection.js", false);
xhr.send();
eval(xhr.responseText);
実行時に含めるのではなく、スクリプトを使用してアップロード前に連結します。
Sprockets を使用します(他に存在するかどうかはわかりません)。 JavaScriptコードを別々のファイルに作成し、Sprocketsエンジンによってインクルードとして処理されるコメントを含めます。開発のためにはファイルを順番にインクルードすることができます、そしてプロダクションのためにそれらをマージするために...
また見なさい:
Web Workers を使用していて、ワーカーの範囲内に追加のスクリプトを含めたい場合は、head
タグへのスクリプトの追加などに関する他の回答は役に立ちません。
幸いなことに、 Webワーカーには独自のimportScripts
関数 があります。これは、Webワーカーのスコープ内にあるグローバル関数で、ブラウザ自体に固有のものです。 は仕様の一部です 。
あるいは、 あなたの質問に対する2番目に高い投票の答えとして 、 RequireJS はWebワーカー内にスクリプトを含めることも処理できます(おそらくimportScripts
自身を呼び出しますが、他の便利な機能もあります)。
私は簡単な問題を抱えていましたが、この質問に対する回答に困惑しました。
あるJavaScriptファイル(myvariables.js)で定義されている変数(myVar1)を別のJavaScriptファイル(main.js)で使用する必要がありました。
このために私は以下のようにしました:
HTMLファイル内のJavaScriptコードを正しい順序で、最初はmyvariables.js、次にmain.jsの順にロードしました。
<html>
<body onload="bodyReady();" >
<script src="myvariables.js" > </script>
<script src="main.js" > </script>
<!-- Some other code -->
</body>
</html>
ファイル:myvariables.js
var myVar1 = "I am variable from myvariables.js";
ファイル:main.js
// ...
function bodyReady() {
// ...
alert (myVar1); // This shows "I am variable from myvariables.js", which I needed
// ...
}
// ...
ご覧のとおり、あるJavaScriptファイル内の変数を別のJavaScriptファイル内で使用していましたが、別のJavaScriptファイルに変数を含める必要はありませんでした。最初のJavaScriptファイルが2番目のJavaScriptファイルの前にロードされ、最初のJavaScriptファイルの変数に2番目のJavaScriptファイルから自動的にアクセスできるようにする必要があります。
これは私の日を救った。これが役に立つことを願っています。
CSS風のJavaScriptインポートを実現するための@import
構文は、Mixtureなどのツールを使用して、特別な.mix
ファイルタイプで使用できます( here を参照)。私は知りませんが、アプリケーションが前述の方法の1つを単純に使用していると思います。
.mix
ファイルに関するMixtureドキュメントから:
ミックスファイルは、単に.mixを持つ.jsファイルまたは.cssファイルです。ファイル名に。 ミックスファイルは、通常のスタイルまたはスクリプトファイルの機能を単純に拡張したもので、インポートと結合を可能にします。
これは、複数の.mix
ファイルを1つにまとめた.js
ファイルの例です。
// scripts-global.mix.js
// Plugins - Global
@import "global-plugins/headroom.js";
@import "global-plugins/retina-1.1.0.js";
@import "global-plugins/isotope.js";
@import "global-plugins/jquery.fitvids.js";
Mixtureはこれをscripts-global.js
および縮小版(scripts-global.min.js
)として出力します。
注意:フロントエンド開発ツールとして使用する以外、私はMixtureと提携していません。 .mix
JavaScriptファイルが(Mixtureボイラープレートの1つで)実際に動作しているのを見て、少し混乱していたときにこの質問に遭遇しました(「あなたはこれを行うことができますか?」。それから私はそれがアプリケーション特有のファイルタイプであることに気づきました(やや残念、同意しました)。それにもかかわらず、知識が他の人に役立つかもしれないと考えました。
_ update _ :混合は 現在無料 (オフライン)です。
_ update _ :混合は中止されました。 古い混合リリース はまだ利用可能です
私のいつもの方法は:
var require = function (src, cb) {
cb = cb || function () {};
var newScriptTag = document.createElement('script'),
firstScriptTag = document.getElementsByTagName('script')[0];
newScriptTag.src = src;
newScriptTag.async = true;
newScriptTag.onload = newScriptTag.onreadystatechange = function () {
(!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') && (cb());
};
firstScriptTag.parentNode.insertBefore(newScriptTag, firstScriptTag);
}
それは素晴らしい仕事と私のためにページのリロードを使用しません。私はAJAXメソッド(他の答えの1つ)を試しましたが、それは私にとってはうまく動作しないようです。
好奇心旺盛な人のためにコードがどのように機能するかを説明します。基本的に、URLの新しいスクリプトタグ(最初のタグの後)を作成します。これを非同期モードに設定して残りのコードをブロックしないようにしますが、readyState(ロードされるコンテンツの状態)が 'loaded'に変わったときにコールバックを呼び出します。
私はJavaScriptでモジュールスクリプトをインポート/インクルードする仕事を自動化する簡単なモジュールを書きました。コードの詳細な説明については、ブログ記事JavaScript require/import/includeモジュールを参照してください。
// ----- USAGE -----
require('ivar.util.string');
require('ivar.net.*');
require('ivar/util/array.js');
require('http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js');
ready(function(){
//Do something when required scripts are loaded
});
//--------------------
var _rmod = _rmod || {}; //Require module namespace
_rmod.LOADED = false;
_rmod.on_ready_fn_stack = [];
_rmod.libpath = '';
_rmod.imported = {};
_rmod.loading = {
scripts: {},
length: 0
};
_rmod.findScriptPath = function(script_name) {
var script_elems = document.getElementsByTagName('script');
for (var i = 0; i < script_elems.length; i++) {
if (script_elems[i].src.endsWith(script_name)) {
var href = window.location.href;
href = href.substring(0, href.lastIndexOf('/'));
var url = script_elems[i].src.substring(0, script_elems[i].length - script_name.length);
return url.substring(href.length+1, url.length);
}
}
return '';
};
_rmod.libpath = _rmod.findScriptPath('script.js'); //Path of your main script used to mark
//the root directory of your library, any library.
_rmod.injectScript = function(script_name, uri, callback, prepare) {
if(!prepare)
prepare(script_name, uri);
var script_elem = document.createElement('script');
script_elem.type = 'text/javascript';
script_elem.title = script_name;
script_elem.src = uri;
script_elem.async = true;
script_elem.defer = false;
if(!callback)
script_elem.onload = function() {
callback(script_name, uri);
};
document.getElementsByTagName('head')[0].appendChild(script_elem);
};
_rmod.requirePrepare = function(script_name, uri) {
_rmod.loading.scripts[script_name] = uri;
_rmod.loading.length++;
};
_rmod.requireCallback = function(script_name, uri) {
_rmod.loading.length--;
delete _rmod.loading.scripts[script_name];
_rmod.imported[script_name] = uri;
if(_rmod.loading.length == 0)
_rmod.onReady();
};
_rmod.onReady = function() {
if (!_rmod.LOADED) {
for (var i = 0; i < _rmod.on_ready_fn_stack.length; i++){
_rmod.on_ready_fn_stack[i]();
});
_rmod.LOADED = true;
}
};
_.rmod = namespaceToUri = function(script_name, url) {
var np = script_name.split('.');
if (np.getLast() === '*') {
np.pop();
np.Push('_all');
}
if(!url)
url = '';
script_name = np.join('.');
return url + np.join('/')+'.js';
};
//You can rename based on your liking. I chose require, but it
//can be called include or anything else that is easy for you
//to remember or write, except "import", because it is reserved
//for future use.
var require = function(script_name) {
var uri = '';
if (script_name.indexOf('/') > -1) {
uri = script_name;
var lastSlash = uri.lastIndexOf('/');
script_name = uri.substring(lastSlash+1, uri.length);
}
else {
uri = _rmod.namespaceToUri(script_name, ivar._private.libpath);
}
if (!_rmod.loading.scripts.hasOwnProperty(script_name)
&& !_rmod.imported.hasOwnProperty(script_name)) {
_rmod.injectScript(script_name, uri,
_rmod.requireCallback,
_rmod.requirePrepare);
}
};
var ready = function(fn) {
_rmod.on_ready_fn_stack.Push(fn);
};
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
現代の言語では
function loadJs( url ){
return new Promise( resolve => {
const script = document.createElement( "script" );
script.src = url;
script.onload = resolve;
document.head.appendChild( script );
});
}
私は便利なJavaScriptプラグインのコレクションを維持する簡単な方法を探していたので、私はこの質問に来ました。ここでいくつかの解決策を見た後、私はこれを思い付きました:
"plugins.js"(またはextensions.jsまたはあなたが持っているもの)というファイルを設定します。その1つのマスターファイルと一緒にあなたのプラグインファイルを保管してください。
plugins.jsは "pluginNames []"と呼ばれる配列を持ち、それをeach()に対して繰り返し、そして各プラグインの先頭にタグを追加します
//プラグインファイルを追加または削除したときに更新される配列を設定する var pluginNames = ["lettering"、 "fittext"、 "butterjam"など]; //スクリプトタグ1つ各プラグイン $ .each(pluginNames、function(){ $( 'head')。append( ''); });
頭の中の1つのファイルだけを手動で呼び出します。<script src="js/plugins/plugins.js"></script>
すべてのプラグインが本来の方法でheadタグにドロップされていたとしても、ページをクリックしたり更新したりしたときにブラウザによって常に実行されているわけではありません。
スクリプトタグをPHPインクルードに記述するだけのほうが信頼性が高いことがわかりました。あなたは一度だけそれを書く必要があり、それはJavaScriptを使ってプラグインを呼び出すのと同じくらい多くの仕事です。
このスクリプトは、他の<script>
タグの先頭にJavaScriptファイルを追加します。
(function () {
var li = document.createElement('script');
li.type = 'text/javascript';
li.src= "http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js";
li.async=true;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(li, s);
})();
この質問に対する多くの潜在的な答えがあります。私の答えは明らかにそれらの数に基づいています。これは私がすべての答えを読んだ後に終わったものです。
$.getScript
やロード完了時にコールバックを必要とする他のソリューションの問題は、それを使用して互いに依存している複数のファイルがある場合、すべてのスクリプトがいつロードされたかを知る方法がもうないことです。複数のファイルにネストされています。
file3.js
var f3obj = "file3";
// Define other stuff
file2.js:
var f2obj = "file2";
$.getScript("file3.js", function(){
alert(f3obj);
// Use anything defined in file3.
});
file1.js:
$.getScript("file2.js", function(){
alert(f3obj); //This will probably fail because file3 is only guaranteed to have loaded inside the callback in file2.
alert(f2obj);
// Use anything defined in the loaded script...
});
Ajaxを指定して同期的に実行することも、 XMLHttpRequest を使用することもできますが、現在の傾向では同期要求は推奨されないため、現在または将来完全なブラウザサポートが得られない場合があります。
$.when
を使って据え置きオブジェクトの配列をチェックすることもできますが、今度はすべてのファイルでこれを行っているので、コールバックの実行時ではなく$.when
が実行されるとすぐにfile2がロードされたと見なされます。ロードされます。これにはまだ同じ問題があります。
私は前進ではなく後退することにしました。 document.writeln
ありがとうございます。私はそれがタブーであることを知っています、しかしそれが正しく使用される限りこれはうまくいきます。簡単にデバッグできるコード、DOMに正しく表示されるコード、そして依存関係が正しくロードされる順序を保証できるコードが得られます。
あなたはもちろん$( "body")。append()を使うことができますが、それからもう正しくデバッグすることはできません。
注:ページの読み込み中にのみこれを使用する必要があります。それ以外の場合は空白の画面が表示されます。言い換えれば、 は常にこれをdocument.ready の前に配置します。クリックイベントなどでページが読み込まれた後は、これを使用したテストは行っていませんが、失敗することは間違いありません。
私はjQueryを拡張するという考えが好きでしたが、明らかにそうする必要はありません。
document.writeln
を呼び出す前に、すべてのスクリプト要素を評価して、スクリプトがまだロードされていないことを確認します。
document.ready
イベントが実行されるまで、スクリプトは完全には実行されません。 (私はdocument.ready
の使用は必須ではないことを知っていますが、多くの人がそれを使用しています、そしてこれを取り扱うことは安全装置です。)
追加ファイルがロードされると、document.ready
コールバックは間違った順序で実行されます。スクリプトが実際にロードされたときにこれに対処するために、それをインポートしたスクリプトはそれ自身を再インポートして実行を停止します。これにより、元のファイルはdocument.ready
コールバックをインポートしたスクリプトから実行された後に実行します。
このアプローチの代わりにjQueryのreadyList
を修正しようと試みることができます、しかしこれはより悪い解決策のように見えました。
溶液:
$.extend(true,
{
import_js : function(scriptpath, reAddLast)
{
if (typeof reAddLast === "undefined" || reAddLast === null)
{
reAddLast = true; // Default this value to true. It is not used by the end user, only to facilitate recursion correctly.
}
var found = false;
if (reAddLast == true) // If we are re-adding the originating script we do not care if it has already been added.
{
found = $('script').filter(function () {
return ($(this).attr('src') == scriptpath);
}).length != 0; // jQuery to check if the script already exists. (replace it with straight JavaScript if you don't like jQuery.
}
if (found == false) {
var callingScriptPath = $('script').last().attr("src"); // Get the script that is currently loading. Again this creates a limitation where this should not be used in a button, and only before document.ready.
document.writeln("<script type='text/javascript' src='" + scriptpath + "'></script>"); // Add the script to the document using writeln
if (reAddLast)
{
$.import_js(callingScriptPath, false); // Call itself with the originating script to fix the order.
throw 'Readding script to correct order: ' + scriptpath + ' < ' + callingScriptPath; // This halts execution of the originating script since it is getting reloaded. If you put a try / catch around the call to $.import_js you results will vary.
}
return true;
}
return false;
}
});
使用法:
ファイル3:
var f3obj = "file3";
// Define other stuff
$(function(){
f3obj = "file3docready";
});
ファイル2:
$.import_js('js/file3.js');
var f2obj = "file2";
$(function(){
f2obj = "file2docready";
});
ファイル1:
$.import_js('js/file2.js');
// Use objects from file2 or file3
alert(f3obj); // "file3"
alert(f2obj); // "file2"
$(function(){
// Use objects from file2 or file3 some more.
alert(f3obj); //"file3docready"
alert(f2obj); //"file2docready"
});
JavaScriptファイルをインクルードするためにC#/ Javaに似た言葉遣いを使用できるようにする関数を作成しました。 another / JavaScriptファイルの内部からでも少しテストしたところ、うまくいったようです。それはjQueryを必要としますが、最後には少し「魔法」が必要です。
このコードを私のスクリプトディレクトリのルートにあるファイルに入れました(私はglobal.js
と名前を付けましたが、あなたは好きなものを使うことができます。これは基本的な使い方以外にはほとんどテストされていないので、私のやり方には問題があるかもしれないし、ないかもしれません;あなた自身の責任で使ってくださいyadda yadda
/**
* @fileoverview This file stores global functions that are required by other libraries.
*/
if (typeof(jQuery) === 'undefined') {
throw 'jQuery is required.';
}
/** Defines the base script directory that all .js files are assumed to be organized under. */
var BASE_DIR = 'js/';
/**
* Loads the specified file, outputting it to the <head> HTMLElement.
*
* This method mimics the use of using in C# or import in Java, allowing
* JavaScript files to "load" other JavaScript files that they depend on
* using a familiar syntax.
*
* This method assumes all scripts are under a directory at the root and will
* append the .js file extension automatically.
*
* @param {string} file A file path to load using C#/Java "dot" syntax.
*
* Example Usage:
* imports('core.utils.extensions');
* This will output: <script type="text/javascript" src="/js/core/utils/extensions.js"></script>
*/
function imports(file) {
var fileName = file.substr(file.lastIndexOf('.') + 1, file.length);
// Convert PascalCase name to underscore_separated_name
var regex = new RegExp(/([A-Z])/g);
if (regex.test(fileName)) {
var separated = fileName.replace(regex, ",$1").replace(',', '');
fileName = separated.replace(/[,]/g, '_');
}
// Remove the original JavaScript file name to replace with underscore version
file = file.substr(0, file.lastIndexOf('.'));
// Convert the dot syntax to directory syntax to actually load the file
if (file.indexOf('.') > 0) {
file = file.replace(/[.]/g, '/');
}
var src = BASE_DIR + file + '/' + fileName.toLowerCase() + '.js';
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = src;
$('head').find('script:last').append(script);
}
これらの答えは素晴らしいですが、スクリプトのロードが存在してからずっと続いている単純な「解決策」があり、それはほとんどの人の使用例の99.999%をカバーするでしょう。必要なスクリプトを必要とするスクリプトの前に含めるだけです。ほとんどのプロジェクトでは、どのスクリプトがどの順序で必要かを判断するのに時間はかかりません。
<!DOCTYPE HTML>
<html>
<head>
<script src="script1.js"></script>
<script src="script2.js"></script>
</head>
<body></body>
</html>
Script2がscript1を必要とする場合、これは本当にこのようなことをするための絶対に最も簡単な方法です。ほとんど明白な最も単純な答えがほとんどすべての場合に当てはまるので、だれもこれを思い付かなかったことに私は非常に驚いています。
Javascriptでモジュールを実装するにはいくつかの方法があります。これが最も人気のある2つの方法です。
ブラウザはまだこのモジュール方式をサポートしていないので、この構文を使用するには、webpackのようなバンドラーを使用する必要があります。とにかくバンドラーを使うほうがよいでしょう。なぜならこれはあなたの異なるファイルの全てを一つの(あるいはカップルに関連した)ファイルにまとめることができるからです。各HTTP要求には付随するオーバーヘッドがあるため、これによりサーバーからクライアントへのファイルの配信が早くなります。したがって、HTTP要求全体を減らすことで、パフォーマンスが向上します。 ES6モジュールの例はここにあります:
// main.js file
export function add (a, b) {
return a + b;
}
export default function multiply (a, b) {
return a * b;
}
// test.js file
import {add}, multiply from './main'; // for named exports between curly braces {export1, export2}
// for default exports without {}
console.log(multiply(2, 2)); // logs 4
console.log(add(1, 2)); // logs 3
この調整システムはNodeJSで使用されています。あなたは基本的にあなたのエクスポートをmodule.exports
と呼ばれるオブジェクトに追加します。それからrequire('modulePath')
を通してこのオブジェクトにアクセスすることができます。ここで重要なのは、これらのモジュールがキャッシュされていることを認識することです。そのため、あるモジュールを2回require()
すると、作成済みのモジュールが返されます。
// main.js file
function add (a, b) {
return a + b;
}
module.exports = add; // here we add our add function to the exports object
// test.js file
const add = require('./main');
console.log(add(1,2)); // logs 3
HTMLインポートを使用した回避策browser(Node.jsではない)の場合)があります。
まず、すべてのJavaScriptクラスとスクリプトは.js
ファイルにはありませんが、.js.html
ファイルには(<script>
タグ内で、.js.html
は単にHTMLページと完全なJavaScriptスクリプト/クラスを区別するため)
MyClass.js.html
:
<script>
class MyClass {
// Your code here..
}
</script>
その後、クラスをインポートしたい場合は、HTMLインポートを使用するだけです。
<link rel="import" href="relative/path/to/MyClass.js.html"/>
<script>
var myClass = new MyClass();
// Your code here..
</script>
HTMLインポートとES6モジュール どちらもすでに世界中のほとんどのブラウザでうまく実装されています 。 しかしHTMLのインポートは間違いなく標準の一部になることはないので、ES6モジュールとは異なり、その開発は中止されます、そしてあなたは間違いなくES6モジュールを使い始めるべきです。
JavaScriptファイルを含むあらゆるファイルで@import "path/to/file.js";
構文を使用できるようにする Grunt プラグインがあります。それはuglifyやwatchあるいは他のプラグインとペアにすることができます。
Npm install: https://npmjs.org/package/grunt-import にインストールできます。
素敵で、短く、シンプルで、保守しやすいものにしてください! :]
// 3rd party plugins / script (don't forget the full path is necessary)
var FULL_PATH = '', s =
[
FULL_PATH + 'plugins/script.js' // Script example
FULL_PATH + 'plugins/jquery.1.2.js', // jQuery Library
FULL_PATH + 'plugins/crypto-js/hmac-sha1.js', // CryptoJS
FULL_PATH + 'plugins/crypto-js/enc-base64-min.js' // CryptoJS
];
function load(url)
{
var ajax = new XMLHttpRequest();
ajax.open('GET', url, false);
ajax.onreadystatechange = function ()
{
var script = ajax.response || ajax.responseText;
if (ajax.readyState === 4)
{
switch(ajax.status)
{
case 200:
eval.apply( window, [script] );
console.log("library loaded: ", url);
break;
default:
console.log("ERROR: library not loaded: ", url);
}
}
};
ajax.send(null);
}
// initialize a single load
load('plugins/script.js');
// initialize a full load of scripts
if (s.length > 0)
{
for (i = 0; i < s.length; i++)
{
load(s[i]);
}
}
このコードは、couldのプラットフォーム(または特定のプラットフォーム)で完全にサポートするために追加の機能を必要とする短い機能的な例です。
基本的には次のようにして、新しい要素を作成し、それをheadに添付します。
var x = document.createElement('script');
x.src = 'http://example.com/test.js';
document.getElementsByTagName("head")[0].appendChild(x);
jQuery :に
// jQuery
$.getScript('/path/to/imported/script.js', function()
{
// Script is now loaded and executed.
// Put your dependent JavaScript code here.
});
NodeJSの場合のみ、これは私にとって最高の結果をもたらしました!
私はここでほとんどの解決策を試してみましたが、スコープを変更せずに他のファイルをロードすることができるだけのことができなかった。最後にこれを使いました。これは範囲とすべてを維持します。それはあなたのコードがその点でそうであるのと同じくらい良いです。
const fs = require('fs');
eval(fs.readFileSync('file.js')+'');
とても簡単です。ファイルA.jsをファイルB.jsにインポートしたいとします。
HTMLファイルでB.jsをリンクしたことを確認したら、そのHTMLファイルでB.jsの前にA.jsをリンクするだけです。そうすればA.jsのパブリック変数はB.jsの中で利用可能になるでしょう
これは複雑な答えを必要としません。
私はJavaScriptファイルの配列を非同期的にロードし、最後にコールバックをするという要件があります。基本的に私の最善のアプローチは次のとおりです。
// Load a JavaScript file from other JavaScript file
function loadScript(urlPack, callback) {
var url = urlPack.shift();
var subCallback;
if (urlPack.length == 0) subCallback = callback;
else subCallback = function () {
console.log("Log script: " + new Date().getTime());
loadScript(urlPack, callback);
}
// Adding the script tag to the head as suggested before
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = subCallback;
script.onload = subCallback;
// Fire the loading
head.appendChild(script);
}
例:
loadScript(
[
"js/DataTable/jquery.dataTables.js",
"js/DataTable/dataTables.bootstrap.js",
"js/DataTable/dataTables.buttons.min.js",
"js/DataTable/dataTables.colReorder.min.js",
"js/DataTable/dataTables.fixedHeader.min.js",
"js/DataTable/buttons.bootstrap.min.js",
"js/DataTable/buttons.colVis.min.js",
"js/DataTable/buttons.html5.min.js"
], function() { gpLoad(params); });
2番目のスクリプトは最初のスクリプトが完全にロードされるまでロードされないので、...
結果:
Angularを使用している場合は、プラグインモジュール $ ocLazyLoad を使用すると便利です。
これがその文書からの引用です。
複数のファイルを持つ1つ以上のモジュールとコンポーネントをロードします。
$ocLazyLoad.load(['testModule.js', 'testModuleCtrl.js', 'testModuleService.js']);
複数のファイルを含む1つまたは複数のモジュールをロードし、必要に応じてタイプを指定します。注:requireJS形式のフォーマットを使用する場合(たとえば先頭にjs!を付けて)、ファイル拡張子を指定しないでください。どちらかを使用してください。
$ocLazyLoad.load([ 'testModule.js', {type: 'css', path: 'testModuleCtrl'}, {type: 'html', path: 'testModuleCtrl.html'}, {type: 'js', path: 'testModuleCtrl'}, 'js!testModuleService', 'less!testModuleLessFile' ]);
あなたは外部ライブラリをロードすることができます(角度ではありません):
$ocLazyLoad.load(['testModule.js', 'bower_components/bootstrap/dist/js/bootstrap.js', 'anotherModule.js']);
Cssファイルとテンプレートファイルを読み込むこともできます。
$ocLazyLoad.load([ 'bower_components/bootstrap/dist/js/bootstrap.js', 'bower_components/bootstrap/dist/css/bootstrap.css', 'partials/template1.html' ]);
.mjs
の代わりに.js
拡張子でファイルに名前を付け
touch main.mjs lib.mjs
import { add } from './lib.mjs';
console.log(add(40, 2));
export let add = (x,y) => {
return x + y
}
node --experimental-modules main.js
今、私は完全に誤解されているかもしれませんが、ここに私が最近始めたものがあります... キャリッジリターンであなたのJavaScriptファイルを始めそして終わり、PHPスクリプトに置き、その後に続きます。キャリッジリターン JavaScriptのコメント "//"はPHPによって無視されるため、いずれにせよ包含は起こります。キャリッジリターンの目的は、含まれているJavaScriptの最初の行がコメントアウトされていないようにすることです。
技術的には、コメントは必要ありませんが、 Dreamweaver にエラーが表示されます。エラーを投稿しないIDEでスクリプトを作成している場合は、コメントやキャリッジリターンは不要です。
\n
//<?php require_once("path/to/javascript/dependency.js"); ?>
function myFunction(){
// stuff
}
\n
var s=["Hscript.js","checkRobert.js","Hscript.js"];
for(i=0;i<s.length;i++){
var script=document.createElement("script");
script.type="text/javascript";
script.src=s[i];
document.getElementsByTagName("head")[0].appendChild(script)
};
忘れずに LAB.js をチェックしてください。
<script type="text/javascript">
$LAB
.script("jquery-1.8.3.js").wait()
.script("scripts/clientscript.js");
</script>
過去のプロジェクトで、再利用可能なJavaScriptファイルのインポートに ajile を使用することでかなり成功しました。私はいつもJavaScript自体に組み込まれたこれのための機能があることを望みました。
別のアプローチはHTMLインポートを使うことです。これらはスタイルシート参照と同様にスクリプト参照を含むことができます。
あなただけのようなHTMLファイルをリンクすることができます
<link rel="import" href="vendorScripts.html"/>
vendorScripts.html
ファイル内に、次のようなスクリプト参照を含めることができます。
<script src="scripts/vendors/jquery.js"></script>
<script src="scripts/vendors/bootstrap.js"></script>
<script src="scripts/vendors/angular.js"></script>
<script src="scripts/vendors/angular-route.js"></script>
詳細については HTML Imports をご覧ください。
残念ながら、これはChromeでしか機能しません。
インポートすることはできませんが、参照することはできます。
PhpShtorm IDE。参照するには、ある.js
ファイルから別の.js
に、これをファイルの先頭に追加します。
<reference path="../js/file.js" />
もちろん、JavaScriptファイルへのあなた自身のPATHを使うべきです。
他のIDEでも動作するかどうかわかりません。おそらくそう、試してみてください。 Visual Studioでも動作するはずです。
はい、 あります...
ES6 で読み続けて、export
name__とimport
name__の一部または全体のJavaScriptファイルを別のファイルに変換できます。
しかし、 ES6 はすべてのブラウザでサポートされているわけではないので、必要なのはbabel.js
を使用して変換することです。
それで、あなたは以下のようなクラスを作成します:
class Person {
constructor(name) {
this.name = name;
}
build() {
return new Person(this);
}
}
module.exports = Person;
別のJavaScriptファイルで、次のようにインポートします。
import { Person } from 'Person';
次のようなファイルも要求できます。
const Person = require('./Person');
古いバージョンのJavaScriptを使用している場合は、 requirejs を使用できます。
requirejs(["helper/util"], function(util) {
//This function is called when scripts/helper/util.js is loaded.
//If util.js calls define(), then this function is not fired until
//util's dependencies have loaded, and the util argument will hold
//the module value for "helper/util".
});
jQuery のように古いバージョンのものに固執したい場合は、 getScript のようなものを使用することもできます。
jQuery.getScript('./another-script.js', function() {
// Call back after another-script loaded
});
大事なことを言い忘れましたが、<script>
タグを使用してスクリプトをまとめる従来の方法を実行できることを忘れないでください。
<script src="./first-script.js"></script>
<script src="./second-script.js"></script>
<script src="./third-script.js"></script>
async および defer 属性もありますが、ここでそれらについて説明します。
注: 外部スクリプトを実行する方法はいくつかあります。
- Asyncが存在する場合:スクリプトはページの残りの部分と非同期に実行されます(スクリプトはページが解析を続けている間に実行されます)。
- Asyncが存在せず、deferが存在する場合:スクリプトは、ページが解析を終了したときに実行されます。
- Asyncもdeferも存在しない場合:スクリプトはフェッチされ、ブラウザがページの解析を続ける前に直ちに実行されます。
これはおそらく別の方法です。 Node.jsでは、次のようにします。 http://requirejs.org/docs/node.html
sub.js
module.exports = {
log: function(string) {
if(console) console.log(string);
}
mylog: function(){
console.log('just for log test!');
}
}
main.js
var mylog =require('./sub');
mylog.log('Hurray, it works! :)');
mylog.mylog();
私はこの問題を別の方法で試しました、
スクリプトインポートの順序は、ここでは効果がありません。
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Trials</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="main.js"></script>
<script src="scriptA.js"></script>
</head>
<body>
<h3>testing js in js (check console logs)</h3>
<button onclick="fnClick()">TEST</button>
</body>
</html>
main.js
function fnClick() {
console.log('From\tAAAAA');
var pro = myExpo.hello();
console.log(pro);
}
scriptA.js
myExpo = {
hello: function () {
console.log('From\tBBBBB');
return "Hello";
}
}
そして 結果 は
From AAAAA
From BBBBB
Hello
ES6:YES scriptタグでtype = "module"を使用(- support )
<script type="module" src="script.js"></script>
そして、script.js
ファイルには、そのような別のファイルが含まれます。
import { hello } from './module.js';
...
// alert(hello());
「module.js」では、 export function/class インポートする必要があります
export function hello() {
return "Hello World";
}
動作中 ここの例 。
2つ以上のスクリプトが呼び出されたときに同じ関数を占有していることがわかった場合は、それらを同じ時間に含めることはできません。ユーザー選択によって 動的 にする必要があります。
$.getScript
を使用してjQuery
に別のファイルをインクルードすることは、スクリプト デフォルトではキャッシュされません 以降で機能します。だから我々は別のスクリプトを呼び出すために保存されています。呼び出しは次のように整理できます。
HTML
<select class="choice">
<option value="script1" selected>Script-1</option>
<option value="script2">Script-2</option>
</select>
JS
$(".choice").change(on_change);
var url = "https://example.com";
$.url1 = url + "/script1.js";
$.url2 = url + "/script2.js";
function on_change() {
if ($(".choice").val()=="script1") {
script1();
} else {
script2();
}
// script1
function script1() {
$.getScript($.url1, function( data, textStatus, jqxhr ) {
//excecute here
});
}
// script2
function script2() {
$.getScript($.url2, function( data, textStatus, jqxhr ) {
//excecute here
});
}
Facebookのアイデアから取られた回答@Dan Dascalescuからlibに少し拡張します。
(function() {
var __ = {};
this._ = function(name, callback) {
if(__[name]==undefined) {
__[name] = true;
var firstScript = document.getElementsByTagName('script')[0],
js = document.createElement('script');
js.src = name;
js.onload = callback;
firstScript.parentNode.insertBefore(js, firstScript);
}
}
})();
(new _('https://cdnjs.cloudflare.com/ajax/libs/Snowstorm/20131208/snowstorm-min.js', function() {
snowStorm.snowColor = '#99ccff';
}));
通常、 静的スクリプト を使用します。それで、私たちは cache からできるだけ多くのものを取得したいのです。
使用方法
$.cachedScript( "ajax/test.js" ).done(function( script, textStatus ) {
console.log( textStatus );
});
cache:true オプションがajaxメソッドに追加されました
var xxx = require("../lib/your-library.js")
または
import xxx from "../lib/your-library.js" //get default export
import {specificPart} from '../lib/your-library.js' //get named export
import * as _name from '../lib/your-library.js' //get full export to alias _name
あなたは私の loadScript ESモジュール を使用することができます - javaScriptファイルのロード。
Headタグに次のコードを含めます。
<script src="https://raw.githack.com/anhr/loadScriptNodeJS/master/build/loadScript.js"></script>
または
<script src="https://raw.githack.com/anhr/loadScriptNodeJS/master/build/loadScript.min.js"></script>
JavaScriptファイルのロードにwindow.loadScriptを使用できます。
非同期ロードJavaScriptファイル。
src:外部スクリプトファイルのURL、またはスクリプトファイル名の配列。
options:フォローされているオプションが利用可能です
onload: function () The onload event occurs when a script has been loaded. Default is undefined.
onerror: function ( str, e ) The onerror event occurs when an error has been occured. Default is undefined.
str: error details
e: event
appendTo: The node to which the new script will be append. Default is head node.
例えば
loadScript.async( "JavaScript.js",
{
onload: function () {
var str = 'file has been loaded successfully';
console.log( str );
},
onerror: function ( str, e ) {
console.error( str );
},
} );
/ - 使用例
1つのスクリプトだけをロードしている場合、または複数のスクリプトのロード順序を気にしていない場合は、上記の関数はうまく機能します。他に依存するスクリプトがある場合は、 Promise を使用してロードの順序を指定する必要があります。その背後にある理由は、Javascriptがスクリプトやイメージなどのリソースを非同期的に読み込むためです。ロードの順序は非同期呼び出しの順序には依存しません。つまり、dynamicallyLoadScript("scrip1")
を呼び出す前にdynamicallyLoadScript("scrip2")
を呼び出しても、script1がscript2の前にロードされることは保証されません。
それで、ロード順を保証するdynamicLoadScriptのもう一つのバージョンがあります:
// Based on: https://javascript.info/promise-basics#example-loadscript
function dynamicallyLoadScript(url) {
return new Promise(function(resolve, reject) {
var script = document.createElement("script");
script.src = url;
script.onload = resolve;
script.onerror = () => reject(new Error(`Error when loading ${url}!`));
document.body.appendChild(script);
});
Promiseの詳細については、 この優れたページ を参照してください。
この新しいdynamicLoadScriptの使い方はとても簡単です。
dynamicallyLoadScript("script1.js")
.then(() => dynamicallyLoadScript("script2.js"))
.then(() => dynamicallyLoadScript("script3.js"))
.then(() => dynamicallyLoadScript("script4.js"))
.then(() => dynamicallyLoadScript("script5.js"))
//...
これで、スクリプトはscript1.js、script2.js、script3.jsなどの順序でロードされました。
さらに、スクリプトをロードした後にそのスクリプトを使用するコードをすぐに実行できます。スクリプトをロードした後に.then
を追加するだけです。
dynamicallyLoadScript("script1.js")
.then(() => dynamicallyLoadScript("script2.js"))
.then(() => foo()) // foo can be a function defined in either script1, script2
.then(() => dynamicallyLoadScript("script3.js"))
.then(() => {
if (var1){ // var1 can be a global variable defined in either script1, script2, or script3
bar(var1); // bar can be a function defined in either script1, script2, or script3
} else {
foo(var1);
}
})
//more .then chains...
未処理の約束拒否(スクリプトのロードエラーなど)を表示するには、このunhandledrejection
イベントリスナをコードの先頭に配置します。
// Based on: https://javascript.info/promise-error-handling#unhandled-rejections
window.addEventListener('unhandledrejection', function(event) {
// the event object has two special properties:
console.error(event.promise);// the promise that generated the error
console.error(event.reason); // the unhandled error object
});
これでスクリプトロードエラーが通知されます。
ロード直後にコードを実行せずに多数のスクリプトをロードする場合は、この短縮形の関数が便利です。
function dynamicallyLoadScripts(urls){
if (urls.length === 0){
return;
}
let promise = dynamicallyLoadScript(urls[0]);
urls.slice(1).forEach(url => {
promise = promise.then(() => dynamicallyLoadScript(url));
});
}
それを使用するには、単に次のようなスクリプトURLの配列を渡します。
const scriptURLs = ["dist/script1.js", "dist/script2.js", "dist/script3.js"];
dynamicallyLoadScripts(scriptURLs);
スクリプトは配列に表示される順序でロードされます。