CSS中是否存在与@import
类似的内容,允许您在另一个JavaScript文件中包含JavaScript文件?
答案 0 :(得分:4025)
旧版本的JavaScript没有导入,包含或要求,因此已经开发了许多不同的方法来解决这个问题。
但自2015年(ES6)以来,JavaScript已经有ES6 modules标准来导入Node.js中的模块,most modern browsers也支持这些模块。
为了与旧版浏览器兼容,可以使用build和/或transpilation工具。
自v8.5起,Node.js支持ECMAScript(ES6)模块,并带有--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这样的工具)since 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
也可以打开错误,黑客和安全问题的大门。
与动态导入类似,您可以使用promises加载一个或多个脚本,并使用Fetch Inject库来控制脚本依赖项的执行顺序:
fetch
jQuery库提供加载功能in one line:
fetchInject([
'https://cdn.jsdelivr.net/momentjs/2.17.1/moment.min.js'
]).then(() => {
console.log(`Finish in less than ${moment().endOf('year').fromNow(true)}`)
})
您可以将带有脚本URL的脚本标记添加到HTML中。为了避免jQuery的开销,这是一个理想的解决方案。
该脚本甚至可以驻留在不同的服务器上。此外,浏览器评估代码。 $.getScript("my_lovely_script.js", function() {
alert("Script loaded but not necessarily executed.");
});
代码可以注入网页<script>
,也可以在结束<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)
}
标记添加到页面头部的末尾,其中<script>
属性设置为作为第一个参数赋予函数的URL。
JavaScript Madness: Dynamic Script Loading中讨论并说明了这两种解决方案。
现在,您必须了解一个大问题。这样做意味着您远程加载代码。现代Web浏览器将加载文件并继续执行当前脚本,因为它们异步加载所有内容以提高性能。 (这适用于jQuery方法和手动动态脚本加载方法。)
这意味着如果您直接使用这些技巧,在您要求加载后,您将无法在下一行使用新加载的代码,因为它仍将加载。
例如:src
包含my_lovely_script.js
:
MySuperObject
然后你重新加载点击 F5 的页面。它的工作原理!混乱...
那该怎么办呢?
好吧,你可以在我给你的链接中使用作者建议的黑客。总之,对于匆忙的人,他在加载脚本时使用事件来运行回调函数。因此,您可以使用远程库将所有代码放在回调函数中。例如:
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
var s = new MySuperObject();
Error : MySuperObject is undefined
然后在lambda function加载脚本后编写要使用的代码:
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
};
请注意,脚本可能在DOM加载之后或之前执行,具体取决于浏览器以及是否包含行loadScript("my_lovely_script.js", myPrettyCode);
。有一个great article on Javascript loading in general讨论了这一点。
正如本答案的顶部所述,许多开发人员在他们的项目中使用像Parcel,Webpack或Babel这样的构建/转换工具,允许他们使用即将推出的JavaScript语法,为旧版浏览器提供向后兼容性,组合文件,缩小,执行代码分割等。
答案 1 :(得分:540)
如果有人想要更高级的东西,请试试RequireJS。您将获得额外的好处,例如依赖关系管理,更好的并发性,并避免重复(即,多次检索脚本)。
您可以在“模块”中编写JavaScript文件,然后在其他脚本中将它们作为依赖项引用。或者您可以将RequireJS用作简单的“go get this script”解决方案。
示例:
将依赖关系定义为模块:
<强>一些-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 是您的“主要”JavaScript文件,依赖于 some-dependency.js
require(['some-dependency'], function(dependency) {
//Your script goes here
//some-dependency.js is fetched.
//Then your script is executed
});
摘自GitHub自述文件:
RequireJS加载纯JavaScript文件以及更多定义 模块。它针对浏览器内使用进行了优化,包括在Web中 工作者,但它可以在其他JavaScript环境中使用,例如 Rhino和Node。它实现了异步模块API。
RequireJS使用普通脚本标签加载模块/文件,因此它应该 允许轻松调试。它可以简单地用于加载现有的 JavaScript文件,因此您可以将其添加到现有项目中 必须重新编写JavaScript文件。
...
答案 2 :(得分:176)
实际上是一种异步加载JavaScript文件而不是的方法,因此您可以在加载后立即使用新加载的文件中包含的函数,我认为它适用于所有浏览器。
您需要在页面的jQuery.append()
元素上使用<head>
,即:
$("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');
我还在Example进行了一次简单的测试。
它在主HTML中包含main.js
文件,然后main.js
中的脚本使用$.import_js()
导入名为included.js
的附加文件,该文件定义了此功能:< / p>
function hello()
{
alert("Hello world!");
}
在包含included.js
之后,调用了hello()
函数,您就会收到警报。
(这个答案是对e-satisf'评论的回应)。
答案 3 :(得分:140)
另一种方式,在我看来更清晰,是制作同步Ajax请求而不是使用<script>
标记。这也是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);
}
});
}
然后您可以在代码中使用它,因为您通常使用include:
require("/scripts/subscript.js");
并且能够在下一行中从所需脚本调用函数:
subscript.doSomethingCool();
答案 4 :(得分:90)
有一个好消息要告诉你。很快您就可以轻松加载JavaScript代码了。它将成为导入JavaScript代码模块的标准方式,并将成为核心JavaScript本身的一部分。
您只需编写import cond from 'cond.js';
即可从文件cond
加载名为cond.js
的宏。
因此,您不必依赖任何JavaScript框架,也不必明确进行Ajax次调用。
参考:
答案 5 :(得分:81)
可以动态生成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");
答案 6 :(得分:62)
语句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;
答案 7 :(得分:52)
也许您可以使用我在此页面上找到的此功能 How do I include a JavaScript file in a JavaScript file? :
function include(filename)
{
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = filename;
script.type = 'text/javascript';
head.appendChild(script)
}
答案 8 :(得分:47)
以下是同步版没有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
标头。
答案 9 :(得分:43)
我刚刚编写了这段JavaScript代码(使用Prototype进行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>
答案 10 :(得分:37)
以下是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/。
答案 11 :(得分:32)
如果您想要纯JavaScript,可以使用document.write
。
document.write('<script src="myscript.js" type="text/javascript"></script>');
如果使用jQuery库,则可以使用$.getScript
方法。
$.getScript("another_script.js");
答案 12 :(得分:25)
您还可以使用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
答案 13 :(得分:24)
此处显示的大多数解决方案都意味着动态加载。我正在搜索一个编译器,它将所有依赖的文件组合成一个输出文件。与Less / Sass预处理程序相同,处理CSS @import
at-rule。由于我没有找到这种类似的东西,我写了一个简单的工具来解决这个问题。
所以这里是编译器https://github.com/dsheiko/jsic,它可以安全地用{1}}替换所请求的文件内容。以下是相应的Grunt插件:https://github.com/dsheiko/grunt-jsic。
在jQuery master分支上,他们只是将原子源文件连接成一个以$import("file-path")
开头并以intro.js
结尾的文件。这不适合我,因为它没有提供源代码设计的灵活性。看看它如何与jsic一起使用:
的src / main.js
outtro.js
SRC /形式/输入/ Tel.js
var foo = $import("./Form/Input/Tel");
现在我们可以运行编译器了:
function() {
return {
prop: "",
method: function(){}
}
}
获取合并文件
建立/ main.js
node jsic.js src/main.js build/mail.js
答案 14 :(得分:20)
如果您打算使用导入/包含文件中的函数加载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>
答案 15 :(得分:18)
这应该做:
xhr = new XMLHttpRequest();
xhr.open("GET", "/soap/ajax/11.0/connection.js", false);
xhr.send();
eval(xhr.responseText);
答案 16 :(得分:17)
或者不是在运行时包含,而是在上传之前使用脚本进行连接。
我使用Sprockets(我不知道是否还有其他人)。您可以在单独的文件中构建JavaScript代码,并包含由Sprockets引擎作为包括处理的注释。对于开发,您可以按顺序包含文件,然后生产以合并它们......
另见:
答案 17 :(得分:14)
如果您使用Web Workers并希望在工作人员范围内包含其他脚本,则提供的有关向head
标记添加脚本等的其他答案将不适合您。
幸运的是,Web Workers have their own importScripts
function是Web Worker范围内的全局函数,它本身就是浏览器本身is part of the specification。
或者,as the second highest voted answer to your question highlights,RequireJS也可以处理Web Worker中的脚本(可能会调用importScripts
本身,但还有一些其他有用的功能)。
答案 18 :(得分:14)
我有一个简单的问题,但我对这个问题的回答感到困惑。
我不得不在另一个JavaScript文件(main.js)中使用一个JavaScript文件(myvariables.js)中定义的变量(myVar1)。
为此我做了如下:
以正确的顺序加载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文件之前加载第一个JavaScript文件,并且第一个JavaScript文件的变量可以在第二个JavaScript文件中自动访问。
这节省了我的一天。我希望这会有所帮助。
答案 19 :(得分:12)
使用Mixture等工具通过其特殊@import
文件类型(参见here),可以实现.mix
语法,以实现类似CSS的JavaScript导入。我想应用程序只是在内部使用上述方法之一,但我不知道。
来自.mix
文件的混合文档:
混合文件只是带有.mix的.js或.css文件。在文件名中。一个 mix文件只是扩展了普通样式的功能 脚本文件,允许您导入和组合。
这是一个示例.mix
文件,它将多个.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";
混合输出为scripts-global.js
,也是缩小版本(scripts-global.min.js
)。
注意:除了将其用作前端开发工具之外,我与Mixture无任何关联。我看到一个.mix
JavaScript文件在运行中(在其中一个混合物样板中)并且被它弄得有点困惑(&#34;你可以这样做?&#34;我想到了自己)时遇到了这个问题)。然后我意识到这是一个特定于应用程序的文件类型(有点令人失望,同意)。然而,认为这些知识可能对其他人有所帮助。
更新:混合为now free(离线)。
更新:混合物现已停止使用。 Old mixture releases仍可用
答案 20 :(得分:11)
我编写了一个简单的模块,可以自动执行在JavaScript中导入/包含模块脚本的工作。有关代码的详细说明,请参阅博客文章 JavaScript require / import / include modules 。
// ----- 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);
};
答案 21 :(得分:11)
我通常的方法是:
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方法(其他一个答案),但它对我来说似乎不太好用。
这里解释了代码如何为那些好奇的人工作:实质上,它创建了一个新的脚本标记(在第一个之后)。它将其设置为异步模式,因此它不会阻止其余代码,但是当readyState(要加载的内容的状态)更改为“已加载”时调用回调。
答案 22 :(得分:11)
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
答案 23 :(得分:10)
在现代语言中它将是
function loadJs( url ){
return new Promise( resolve => {
const script = document.createElement( "script" );
script.src = url;
script.onload = resolve;
document.head.appendChild( script );
});
}
答案 24 :(得分:9)
此脚本会将JavaScript文件添加到任何其他<script>
标记的顶部:
(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);
})();
答案 25 :(得分:9)
还有Head.js。这很容易处理:
head.load("js/jquery.min.js",
"js/jquery.someplugin.js",
"js/jquery.someplugin.css", function() {
alert("Everything is ok!");
});
如您所见,它比Require.js更容易,并且与jQuery的$.getScript
方法一样方便。它还具有一些高级功能,如条件加载,特征检测和much more。
答案 26 :(得分:9)
我遇到了这个问题,因为我正在寻找一种简单的方法来维护一组有用的JavaScript插件。在看到这里的一些解决方案之后,我想出了这个:
设置一个名为&#34; plugins.js&#34;的文件。 (或extensions.js或你有什么)。将您的插件文件与一个主文件保持在一起。
plugins.js将有一个名为&#34; pluginNames []&#34;的数组。我们将遍历每个(), 然后在每个插件的头部附加一个标签
//在我们添加或删除插件文件时设置要更新的数组 var pluginNames = [&#34;刻字&#34;,&#34; fittext&#34;,&#34; butterjam&#34;等等]; //每个插件的一个脚本标记 $ .each(pluginNames,function(){ $(&#39;头&#39;)。追加(&#39;&#39;); });
手动调用你头脑中的一个文件:
<script src="js/plugins/plugins.js"></script>
我发现即使所有的插件都按照他们应该的方式被放入头标签,但当你点击页面或刷新时,他们并不总是被浏览器运行。
我发现在PHP包中编写脚本标记更加可靠。您只需编写一次,这与使用JavaScript调用插件一样多。
答案 27 :(得分:8)
这个问题有很多潜在的答案。我的回答显然基于其中的一些。这是我在阅读完所有答案后最终得到的结果。
$.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将被视为已加载执行回调,因此file1在加载file3之前仍然继续执行。这仍然有同样的问题。
我决定倒退而不是前锋。谢谢document.writeln
。我知道这是禁忌,但只要使用得当,这种方法效果很好。您最终得到的代码可以轻松调试,正确显示在DOM中,并且可以确保正确加载依赖项的顺序。
你当然可以使用$(&#34; body&#34;)。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";
});
File1中:
$.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"
});
答案 28 :(得分:7)
虽然这些答案很棒,但是有一个简单的“解决方案”,因为脚本加载已存在,它将覆盖大多数人的99.999%的用例。只需在需要它的脚本之前包含所需的脚本。对于大多数项目来说,确定需要哪些脚本以及按什么顺序确定需要很长时间。
<!DOCTYPE HTML>
<html>
<head>
<script src="script1.js"></script>
<script src="script2.js"></script>
</head>
<body></body>
</html>
如果script2需要script1,这确实是做这样的事情的绝对最简单的方法。我很惊讶没有人提出这个问题,因为这是几乎每一个案例中最明显和最简单的答案。
答案 29 :(得分:7)
我创建了一个函数,允许您使用与C#/ Java类似的措辞来包含JavaScript文件。我甚至从另一个 JavaScript文件中进行了一些测试,它似乎也有效。它确实需要jQuery,但最后需要一些“魔法”。
我将此代码放在脚本目录根目录下的文件中(我将其命名为global.js
,但您可以使用任何您想要的内容。除非我错了,否则jQuery应该是唯一需要的脚本请注意,除了一些基本用法之外,这在很大程度上是未经测试的,因此我可能会或可能不会出现任何问题;使用风险yadda yadda如果你搞砸了什么,我不负责任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);
}
答案 30 :(得分:6)
我基本上像下面这样做,创建一个新元素并将其附加到头部:
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.
});
答案 31 :(得分:6)
以下是使用HTML导入的 for browsers (非Node.js)的解决方法。
首先,所有JavaScript类和脚本都不在.js
个文件中,但在.js.html
个文件中( .js 。html
只是为了识别HTML页面和完整的JavaScript脚本/类),在<script>
标记内,如下所示:
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模块are both already well implemented in most browser accross the world。 但,因为HTML导入绝对不会成为标准的一部分,与ES6模块不同,它的开发将被删除,那么你应该明确地开始使用ES6模块。
答案 32 :(得分:6)
有几种方法可以用Javascript实现模块,以下是两种最受欢迎的方法:
浏览器尚不支持此调制系统,因此,要使您使用此语法,必须使用像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')
访问该对象。在这里重要的是要意识到这些模块已被缓存,因此,如果您两次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
答案 33 :(得分:6)
保持简洁,简洁,易于维护! :
// 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]);
}
}
此代码只是一个简短的功能示例,可能需要其他功能,以便在任何(或给定)平台上提供全面支持。
答案 34 :(得分:6)
这是一个Grunt插件,允许您在包含JavaScript文件的任何文件中使用@import "path/to/file.js";
语法。它可以与uglify或手表或任何其他插件配对。
可以使用npm install:https://npmjs.org/package/grunt-import
进行安装答案 35 :(得分:6)
更好地使用jQuery方式。要延迟就绪事件,请先致电$.holdReady(true)
。
示例(source):
$.holdReady(true);
$.getScript("myplugin.js", function() {
$.holdReady(false);
});
答案 36 :(得分:5)
仅适用于NodeJS,这对我来说是最好的!
我在这里尝试了大多数解决方案,但是在不更改范围的情况下仅加载另一个文件并没有帮助我。最后我用了这个。保留范围和所有内容。这与您的代码一样好。
const fs = require('fs');
eval(fs.readFileSync('file.js')+'');
答案 37 :(得分:4)
这很简单。假设您要在文件B.js中导入文件A.js。
现在确定您已在HTML文件中链接了B.js,然后在该HTML文件中将B.js链接到B.js之前。然后A.js的公共变量将在B.js
中提供这不需要复杂的答案。
答案 38 :(得分:4)
如果你使用Angular,那么插件模块$ocLazyLoad可以帮助你做到这一点。
以下是其文档中的一些引用:
加载一个或多个模块&amp;包含多个文件的组件:
$ocLazyLoad.load(['testModule.js', 'testModuleCtrl.js', 'testModuleService.js']);
使用多个文件加载一个或多个模块,并在必要时指定类型: 注意:使用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' ]);
答案 39 :(得分:4)
是的,有......
继续阅读,在 ES6 中,我们可以将export
和import
部分或整个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 属性,我应该在这里提一下......
注意:有多种方法可以执行外部脚本:
- 如果存在异步:脚本以异步方式执行 与页面的其余部分(脚本将在页面执行 继续解析)
- 如果不存在异步并且延迟是 present:页面完成后执行脚本 解析
- 如果不存在异步或延迟:脚本是 在浏览器继续之前立即获取并执行 解析页面
答案 40 :(得分:4)
我要求异步加载一系列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); });
第二个脚本在第一个脚本完全加载之前不会加载,所以......
结果:
答案 41 :(得分:3)
扩展名为.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
答案 42 :(得分:3)
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)
};
答案 43 :(得分:3)
现在,我可能完全被误导了,但这是我最近开始做的...... 使用回车符开始和结束JavaScript文件,放在PHP脚本中,然后再回车一次。 PHP会忽略JavaScript注释“//”,因此无论如何都会包含。回车的目的是使所包含的JavaScript的第一行不被注释掉。
从技术上讲,您不需要评论,但它会在Dreamweaver中发布令我烦恼的错误。如果您在不发布错误的IDE中编写脚本,则不需要注释或回车。
\n
//<?php require_once("path/to/javascript/dependency.js"); ?>
function myFunction(){
// stuff
}
\n
答案 44 :(得分:3)
不要忘记查看LAB.js!
<script type="text/javascript">
$LAB
.script("jquery-1.8.3.js").wait()
.script("scripts/clientscript.js");
</script>
答案 45 :(得分:3)
在过去的项目中,我使用ajile来导入可重用的JavaScript文件取得了相当大的成功。我一直希望有一个内置于JavaScript本身的功能。
答案 46 :(得分:2)
我用另一种方法尝试了这个问题,
脚本导入的顺序在这里无效。
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
答案 47 :(得分:2)
您无法导入,但可以参考。
PhpShtorm IDE。要在一个.js
文件中引用另一个.js
,只需将其添加到文件顶部:
<reference path="../js/file.js" />
当然,您应该将自己的PATH用于JavaScript文件。
我不知道它是否适用于其他IDE。可能是的,试试吧。它也应该在Visual Studio中工作。
答案 48 :(得分:2)
另一种方法是使用HTML导入。这些可以包含脚本引用以及样式表引用。
您只需链接HTML文件,例如
Imports Microsoft.VisualBasic.PowerPacks
Public Class MDIParent1
Dim C As New ShapeContainer
Dim WithEvents R As New RectangleShape
Private Sub MDIParent1_Load(sender As Object, e As EventArgs) Handles Me.Load
C.Parent = Me
R.Parent = C
R.Top = 0
R.Left = 0
Me.Controls.Add(C)
End Sub
Private Sub MDIParent1_Resize(sender As Object, e As EventArgs) Handles Me.Resize
R.Height = Me.Height
R.Width = Me.Width
End Sub
Private Sub R_DoubleClick(sender As Object, e As EventArgs) Handles R.DoubleClick
MessageBox.Show("Shape Double-click")
End Sub
...
End Class
在<link rel="import" href="vendorScripts.html"/>
文件中,您可以包含脚本引用,例如:
vendorScripts.html
请查看HTML Imports了解更多详情。
不幸的是,这仅适用于Chrome。
答案 49 :(得分:2)
这可能是另一种方式!在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();
答案 50 :(得分:1)
这是一个极端的情况。但是,如果您需要从远程源加载JavaScript,则大多数现代浏览器可能会由于CORS或类似原因而阻止您的跨站点请求。很正常
<script src="https://another-domain.com/example.js"></script>
不起作用。并且执行document.createElement('script').src = '...'
也不会削减。相反,您可以做的是通过标准GET
请求将Java脚本作为资源加载,然后执行以下操作:
<script type="text/javascript">
var script = document.createElement('script');
script.type = 'text/javascript';
let xhr = new XMLHttpRequest();
xhr.open("GET", 'https://raw.githubusercontent.com/Torxed/slimWebSocket/master/slimWebSocket.js', true);
xhr.onreadystatechange = function() {
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
script.innerHTML = this.responseText; // <-- This one
document.head.appendChild(script);
}
}
xhr.send();
</script>
通过自己抓取内容,浏览器将不会发现恶意意图,并允许您执行请求。然后,将其添加到<script>
的{{1}}中。这仍然会导致浏览器(至少在Chrome中经过测试)解析/执行脚本。
同样,这是一个边缘案例用例。而且您可能没有向后兼容性或浏览器兼容性。但是有趣/有用的事情。
答案 51 :(得分:1)
Step 1: Declare the function in another class.
export const myreport = (value) => {
color = value.color;
name = value.name;
var mytext = name + " | " + color;
return mytext;
}
Step 2:- Import that function which is needed to be used.
import {myreport} from '../../Test'
Step 3:- Use that function.
let val = { color: "red", name: "error" }
var resultText = myreport(val)
console.log("resultText :- ", resultText)
答案 52 :(得分:1)
发出 fetch
请求并 eval
结果。
答案 53 :(得分:1)
我的通用解决方案取自 EdgeS (我编写的) 的 efekt.js.st
库。
无耻的插件警报 - 我在其他 stackexchange 网络站点上。这是 https://codereview.stackexchange.com/questions/263764/dynamic-load-css-or-script
的重新链接。
您将使用什么代码或设计来支持 css
和 scripts
的动态加载?
要求
head
、body
或当前 script-element
中的负载css
、js
、mjs
模块或其他脚本类型nonce
、crossorigin
等static loadScriptOrStyle(url, options) {
// provenance :<# **Smallscript EdgeS efekt** `efekt.js.st` github libraries #>
// returns :<Promise#onload;onerror>
// options :<# `fIgnoreCache`, `fAppendToHead`, `fUrlIsStyle`, `attrs:{}` #>
const head = document.head; let node = options?.fAppendToBody ? document.body : head;
const url_loader_cache = document.head.url_loader_cache
? head.url_loader_cache
: (head.url_loader_cache = {script:{},link:{}})
const kind = (options?.fUrlIsStyle || /\.css(?:(?:\?|#).*)?$/i.test(url))
? 'link' : 'script';
// check already-loaded cache
if(url_loader_cache[kind][url]) {
const el = url_loader_cache[kind][url];
// support `fIgnoreCache` reload-option; should not use on `head`
if(options?.fIgnoreCache)
el.remove();
else
return(new CustomEvent('cache',{detail:el}));
}
// (re)create and record it
const self = document.currentScript;
const el = url_loader_cache[kind][url] = document.createElement(kind);
const append = (!self || options?.fAppendToHead || options?.fAppendToBody)
? el => node.appendChild(el)
: el => self.parentNode.insertBefore(el, self);
const load = new Promise((resolve, reject) => {
el.onload = e => {e.detail = el;resolve(e)};
el.onerror = e => {e.detail = el;reject(e)};
// `onload` or `onerror` possibly alter `cache` value
// throw(new URIError(`The ${url} didn't load correctly.`))
});
// configure `module` attr, as appropriate
if(/\.mjs(?:(?:\?|#).*)?$/i.test(url))
el.type = 'module'
// configure other attrs as appropriate (referrer, nonce, etc)
for(const key in options?.attrs) {el[key] = attrs[key]}
// trigger it
if(kind === 'link') el.rel = 'stylesheet', el.href = url; else el.src = url;
append(el);
return(load);
}
答案 54 :(得分:0)
如果您发现有2个或更多脚本在调用时占用相同的功能,那么我们不能同时包含它们,我们需要通过用户选择动态。< / p>
使用jQuery
在$.getScript
中包含其他文件,自脚本will not be cached by default起作用。所以我们保存以调用另一个脚本。电话可以安排如下:
<强> 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
});
}
答案 55 :(得分:0)
请注意,我们通常使用静态脚本。所以我们希望尽可能地从缓存中获取。 这样可以节省网络流量并加快着陆速度。
用法的
$.cachedScript( "ajax/test.js" ).done(function( script, textStatus ) {
console.log( textStatus );
});
cache:true 选项已添加到ajax方法
答案 56 :(得分:0)
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
答案 57 :(得分:0)
如果仅加载一个脚本,或者您不关心多个脚本的加载顺序,则上述功能可以正常工作。如果某些脚本依赖于其他脚本,则需要使用Promise来指定加载顺序。其背后的原因是Javascript异步加载了诸如脚本和图像之类的资源。加载顺序不取决于异步调用的顺序,这意味着即使在调用dynamicallyLoadScript("scrip1")
之前调用dynamicallyLoadScript("scrip2")
因此,这是保证加载顺序的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);
});
有关承诺的更多信息,请参见this excellent page。
这个新的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));
});
}
要使用它,只需传递如下这样的脚本网址数组即可:
const scriptURLs = ["dist/script1.js", "dist/script2.js", "dist/script3.js"];
dynamicallyLoadScripts(scriptURLs);
脚本将按照它们在数组中出现的顺序进行加载。
答案 58 :(得分:0)
您可以使用我的loadScript ES module加载JavaScript文件。
在您的head标签中,包含以下代码:
<script src="https://raw.githack.com/anhr/loadScriptNodeJS/master/build/loadScript.js"></script>
现在,您可以使用window.loadScript加载JavaScript文件。
异步加载JavaScript文件。
src:外部脚本文件的URL或脚本文件名的数组。
选项:以下选项可用
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 );
},
} );
答案 59 :(得分:0)
从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';
}));
答案 60 :(得分:0)
ES6:是,在脚本标签(support)中使用type =“ module”
<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";
}
工作example here。
答案 61 :(得分:0)
我没有看到一个答案,即您在一个文件中创建一个包含所有函数和变量的对象,然后将该对象用作在另一个文件中引用该对象的参数。
例如,您拥有名为“ jsMod.js”,“ jsView”和“ jsContr.js”的文件:
//jsMod.js file
JSMODOBJ = {};
JSMODOBJ.valueAddition = function(/* element value 1 */ val1,
/* element value 2 */ val2) {
return val1 + val2;
}
//jsView.js file
JSVIEWOBJ = {};
JSVIEWOBJ.elementColour = function(/* element id to change colour */ id,
/* css colour classname */ col) {
document.getElementById(id).className = col;
}
//jsContr.js file
JSCONTROBJ = {};
var jsMod = JSMODOBJ;
var jsView = JSVIEWOBJ;
JSCONTROBJ.changeColourByValue = function (val1, val2, id, clss) {
if (jsMod.valueAddition(val1,val2) !== 0) {
jsView.elementColour(id, clss);
}
}
然后,您可以通过将scripts
回显到.html或.php文件中来动态设置.js文件:
<?php
echo "<script src = './js/dleafView.js'></script>
<script src = './js/dleafModule.js'></script>
<script src = './js/dleafContr.js'></script>";
?>
然后只需在<script type="text/javascript"></script>
标记内调用控制函数。当然,从一开始就需要花费很多时间,但是从长远来看,它可以节省您的时间。
我以稍微不同的方式使用它,但是这种方式也可以。
答案 62 :(得分:0)
您还可以将gulp
,gulp-concat
,gulp-typescript
与/// <reference path=
包括:
packages.json
{
"scripts": {
"gulp": "gulp main"
},
"dependencies": {
"@types/gulp": "^4.0.6",
"@types/gulp-concat",
"@types/gulp-typescript",
"gulp": "^4.0.2",
"gulp-concat": "^2.6.1",
"gulp-resolve-dependencies": "^3.0.1",
"gulp-typescript": "^6.0.0-alpha.1",
"typescript": "^3.7.3"
}
}
src / someimport.ts
class SomeClass {
delay: number;
}
src / main.ts
/// <reference path="./someimport.ts" />
someclass = new SomeClass();
someclass.delay = 1;
此main
gulp任务(在gulpfile.js
上)仅针对src/main.js
文件,从而解决了其所有/// <reference path=...
包含引用。这些包括称为Triple-Slash Directives
,它们仅用于编译器工具来组合文件。在我们的情况下,.pipe(resolveDependencies({
和打字稿本身会在检查文件中是否缺少类型,变量等时明确使用它们。
如果您想自定义var tsProject = ts.createProject
调用而不使用tsconfig.json
文件或覆盖其参数,请参考https://github.com/ivogabe/gulp-typescript#api-overview。
gulpfile.js
var gulp = require("gulp");
var concat = require('gulp-concat');
var resolveDependencies = require('gulp-resolve-dependencies');
var ts = require("gulp-typescript");
var tsProject = ts.createProject("tsconfig.json");
gulp.task("main", function() {
return gulp
.src(["src/main.ts"])
.pipe(resolveDependencies({
pattern: /^\s*\/\/\/\s*<\s*reference\s*path\s*=\s*(?:"|')([^'"\n]+)/gm
}))
.on('error', function(err) {
console.log(err.message);
})
.pipe(tsProject())
.pipe(concat('main.js'))
.pipe(gulp.dest("build/"));
});
如果您希望将所有类型脚本项目文件作为目标,而不仅仅是src/main.ts
,则可以替换为:
return gulp
.src(["src/main.ts"])
.pipe(resolveDependencies({
...
// -->
return tsProject
.src()
.pipe(resolveDependencies({
...
如果您不想使用typescript
,则可以使用此简化的gulpfile.js
并从typescript
中删除所有package.json
包含的内容:
gulpfile.js
var gulp = require("gulp");
var concat = require('gulp-concat');
var resolveDependencies = require('gulp-resolve-dependencies');
gulp.task("main", function() {
return gulp
.src(["src/main.js"])
.pipe(resolveDependencies({
pattern: /^\s*\/\/\/\s*<\s*reference\s*path\s*=\s*(?:"|')([^'"\n]+)/gm
}))
.on('error', function(err) {
console.log(err.message);
})
.pipe(concat('main.js'))
.pipe(gulp.dest("build/"));
});
packages.json
{
"scripts": {
"gulp": "gulp main"
},
"dependencies": {
"gulp": "^4.0.2",
"gulp-concat": "^2.6.1",
"gulp-resolve-dependencies": "^3.0.1"
}
}
然后,在运行命令npm run gulp
之后,将创建文件build/main.js
,其内容如下:
build / main.js
class SomeClass {
}
/// <reference path="./someimport.ts" />
someclass = new SomeClass();
someclass.delay = 1;
在提供script
目录文件后,允许我使用build
标签在浏览器中添加它:
<html>
<head>
<script src="main.js"></script>
</head>
<body>
<script type="text/javascript">
console.log(someclass.delay);
</script>
</body>
</html>
相关问题:
答案 63 :(得分:-3)
您应使用此:
<script src="your_file.js"></script>
容易!