博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何在另一个JavaScript文件中包含一个JavaScript文件?
阅读量:2291 次
发布时间:2019-05-09

本文共 24159 字,大约阅读时间需要 80 分钟。

中是否有类似于CSS中@的内容,可让您在另一个JavaScript文件中包含一个JavaScript文件?


#1楼

而不是在运行时添加,而是使用脚本在上传之前进行串联。

我使用 (我不知道是否还有其他 )。 您将JavaScript代码构建在单独的文件中,并包含由Sprockets引擎处理的注释(包括)。 对于开发,您可以依次包含文件,然后在生产中将它们合并...

也可以看看:


#2楼

如果有人在寻找更高级的东西,请尝试 。 您将获得更多好处,例如依赖管理,更好的并发性,并避免重复(也就是说,多次检索脚本)。

您可以在“模块”中编写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是您的“主要” JavaScript文件,它取决于some-dependency.js

require(['some-dependency'], function(dependency) {    //Your script goes here    //some-dependency.js is fetched.       //Then your script is executed});

摘自自述文件:

RequireJS加载普通的JavaScript文件以及更多定义的模块。 它针对浏览器内使用进行了优化,包括在Web Worker中使用,但可以在其他JavaScript环境(例如Rhino和Node)中使用。 它实现了异步模块API。

RequireJS使用简单的脚本标签来加载模块/文件,因此应便于调试。 它可以简单地用于加载现有的JavaScript文件,因此您可以将其添加到现有项目中,而无需重新编写JavaScript文件。

...


#3楼

有个好消息对你来说。 很快,您将能够轻松加载JavaScript代码。 这将成为导入JavaScript代码模块的标准方法,并将成为核心JavaScript本身的一部分。

您只需import cond from 'cond.js';编写import cond from 'cond.js'; 从文件cond.js加载名为cond的宏。

因此,您不必依赖任何JavaScript框架,也不必显式进行调用。

参考:


#4楼

var js = document.createElement("script");js.type = "text/javascript";js.src = jsPath;document.body.appendChild(js);

#5楼

应该这样做:

xhr = new XMLHttpRequest();xhr.open("GET", "/soap/ajax/11.0/connection.js", false);xhr.send();eval(xhr.responseText);

#6楼

我编写了一个简单的模块,该模块可以自动执行导入/包含JavaScript中的模块脚本的工作。 有关代码的详细说明,请参阅博客文章

// ----- 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);};

#7楼

我通常的方法是:

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方法(其他答案之一),但它似乎对我来说效果不佳。

这是代码对好奇的人如何工作的解释:从本质上讲,它会创建URL的新脚本标签(在第一个脚本标签之后)。 它将其设置为异步模式,因此它不会阻塞其余代码,但是会在readyState(要加载的内容的状态)更改为“已加载”时调用回调。


#8楼

此处显示的大多数解决方案都暗含动态载荷。 我搜索的是一个将所有依赖文件组合成单个输出文件的编译器。 与 / 预处理器处理CSS @import规则相同。 由于找不到类似的东西,因此我编写了一个简单的工具来解决此问题。

因此,这里是编译器 ,该编译器将$import("file-path")安全地替换$import("file-path")所请求的文件内容。 这是相应的插件: : 。

在jQuery master分支上,它们只是将原子源文件连接到一个以intro.js开始,以intro.js结尾的outtro.js 。 那不适合我,因为它在源代码设计上没有灵活性。 看看jsic的工作原理:

src / main.js

var foo = $import("./Form/Input/Tel");

src /表格/输入/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(){}    }};

#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);})();

#10楼

如果要使用纯JavaScript,则可以使用document.write

document.write('');

如果使用jQuery库,则可以使用$.getScript方法。

$.getScript("another_script.js");

#11楼

还有 这很容易处理:

head.load("js/jquery.min.js",          "js/jquery.someplugin.js",          "js/jquery.someplugin.css", function() {  alert("Everything is ok!");});

如您所见,它比Require.js更容易,并且与jQuery的$.getScript方法一样方便。 它也有一些先进的功能,如条件装载,特征检测和 。


#12楼

这是没有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标头。


#13楼

我刚刚编写了以下JavaScript代码(使用进行操作):

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);        }    });})();

用法:

要点: : 。


#14楼

使用诸如Mixture之类的工具通过其特殊的.mix文件类型可以使用@import语法来实现类似CSS的JavaScript导入(请参见 )。 我想该应用程序只是内部使用一种上述方法,尽管我不知道。

从关于.mix文件的Mixture文档中:

混合文件只是带.mix的.js或.css文件。 在文件名中。 混合文件只是扩展了普通样式或脚本文件的功能,并允许您导入和合并。

这是一个示例.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";

Mixture将其输出为scripts-global.js和缩小版本( scripts-global.min.js )。

注意:除了使用它作为前端开发工具之外,我与Mixture无关。 我看到一个正在运行的.mix JavaScript文件(在Mixture样板中)时遇到了这个问题,并对此感到有些困惑(“我能做到吗?”)。 然后我意识到这是一个特定于应用程序的文件类型(有些令人失望,同意)。 但是,认为这些知识可能对其他人有所帮助。

更新 :混合物 (脱机)。

更新 :混合物现已停产。 仍然可用


#15楼

如果您正在使用并希望在worker范围内包括其他脚本,则提供的其他有关将脚本添加到head标签等的答案将对您不起作用。

幸运的是, ,它是范围内的全局函数,它浏览器本身的固有特性,因为它 。

或者, , 还可以处理Web Worker中包含的脚本(可能调用importScripts本身,但还具有其他一些有用的功能)。


#16楼

这个问题有很多潜在的答案。 我的答案显然基于其中的一些。 这是我看完所有答案后得出的结论。

$.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同步运行或使用 ,这是对的,但是当前的趋势似乎是弃用同步请求,因此您现在或将来可能无法获得完整的浏览器支持。

您可以尝试使用$.when检查延迟对象的数组,但是现在您正在每个文件中执行此操作,并且$.when在执行时(而不是在执行回调时)将被视为立即加载file2 $.when在加载file3之前继续执行。 这确实仍然存在相同的问题。

我决定后退而不是前进。 谢谢document.writeln 。 我知道这是忌讳的,但是只要正确使用它就可以了。 您最终得到的代码可以轻松调试,可以在DOM中正确显示,并且可以确保正确加载依赖项的顺序。

您当然可以使用$(“ body”)。append(),但随后您将无法再正确调试。

注意:仅在页面加载时才必须使用此选项,否则将出现空白屏幕。 换句话说,请始终将其放在document.ready之前/之外 。 在将页面加载到click事件或类似事件之后,我还没有使用此工具进行过测试,但是我敢肯定它会失败。

我喜欢扩展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(""); // 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 file3alert(f3obj); // "file3"alert(f2obj); // "file2"$(function(){    // Use objects from file2 or file3 some more.    alert(f3obj); //"file3docready"    alert(f2obj); //"file2docready"});

#17楼

语句在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;

#18楼

这是Facebook如何针对其无处不在的“赞”按钮执行此操作的通用版本:

如果它适用于Facebook,它将为您服务。

我们寻找第一个script元素而不是headbody的原因是因为某些浏览器在缺少时不会创建一个script元素,但是我们保证有一个script元素-这个。 请访问了解更多 。


#19楼

我有一个简单的问题,但对这个问题的回答感到困惑。

我必须使用在另一个JavaScript文件(main.js)中的一个JavaScript文件(myvariables.js)中定义的变量(myVar1)。

为此,我这样做如下:

以正确的顺序将JavaScript代码加载到HTML文件中,首先是myvariables.js,然后是main.js:

                            

文件: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文件的变量。

这挽救了我的一天。 我希望这有帮助。


#20楼

如果要加载JavaScript文件的目的是使用导入/包含的文件中的函数 ,则还可以定义一个全局对象并将这些函数设置为对象项。 例如:

global.js

A = {};

file1.js

A.func1 = function() {  console.log("func1");}

file2.js

A.func2 = function() {  console.log("func2");}

main.js

A.func1();A.func2();

在HTML文件中包含脚本时,只需要小心即可。 顺序应如下所示:

        

#21楼

用现代语言来说

function loadJs( url ){  return new Promise( resolve => {    const script = document.createElement( "script" );    script.src = url;    script.onload = resolve;    document.head.appendChild( script );  });}

#22楼

您也可以使用汇编脚本:

文件main.js.php

// Main JavaScript code goes here

#23楼

尽管这些答案很不错,但是自从脚本加载就存在一个简单的“解决方案”,它将覆盖大多数人的99.999%用例。 只需在需要脚本之前添加所需脚本即可。 对于大多数项目,不需要很长时间就能确定需要哪些脚本以及顺序如何。

                            

如果script2需要script1,那么这实际上是绝对简单的方法。 我很惊讶没有人提出这个建议,因为这是几乎在每种情况下都适用的最明显,最简单的答案。


#24楼

有几种方法可以用Javascript实现模块,以下是两种最流行的方法:

ES6模块

浏览器尚不支持此调制系统,因此,要使用此语法,必须使用捆绑程序(例如webpack)。 无论如何,使用捆绑器会更好,因为这可以将所有不同的文件合并为一个(或几个相关的)文件。 这将更快地将文件从服务器传送到客户端,因为每个HTTP请求都伴随有一些相关的开销。 因此,通过减少总体HTTP请求,我们可以提高性能。 这是ES6模块的示例:

// main.js fileexport function add (a, b) {  return a + b;}export default function multiply (a, b) {  return a * b;}// test.js fileimport {add}, multiply from './main';   // for named exports between curly braces {export1, export2}                                        // for default exports without {}console.log(multiply(2, 2));  // logs 4console.log(add(1, 2));  // logs 3

CommonJS (在NodeJS中使用)

此调制系统用于NodeJS。 基本上,您将导出添加到名为module.exports的对象中。 然后,您可以通过require('modulePath')访问该对象。 在这里重要的是要意识到这些模块已被缓存,因此,如果您对某个模块两次require() ,它将返回已经创建的模块。

// main.js filefunction add (a, b) {  return a + b;}module.exports = add;  // here we add our add function to the exports object// test.js fileconst add = require('./main'); console.log(add(1,2));  // logs 3

#25楼

实际上, 一种方法可以异步加载JavaScript文件,因此您可以在加载后立即使用新加载的文件中包含的功能,而且我认为它可以在所有浏览器中使用。

您需要在页面的<head>元素上使用jQuery.append() ,即:

$("head").append('');

但是,此方法也有一个问题:如果在导入的JavaScript文件中发生错误,则 (以及Firefox错误控制台和 )也会错误地报告其位置,如果您使用Firebug进行跟踪,这将是一个大问题JavaScript错误很多(我愿意)。 Firebug出于某种原因根本不了解新加载的文件,因此,如果该文件中发生错误,它将报告该错误是在您的主文件中发生的,您将很难找到导致该错误的真正原因。

但是,如果这对您来说不是问题,则此方法应该有效。

我实际上已经编写了一个使用此方法的名为$ .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('');                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的评论的回应)。


#26楼

我认为更干净的另一种方法是发出同步Ajax请求,而不使用<script>标签。 处理的内容也包括在内。

这是使用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();

#27楼

我之所以提出这个问题,是因为我在寻找一种简单的方法来维护一组有用的JavaScript插件。 在这里看到一些解决方案后,我想到了:

  1. 设置一个名为“ plugins.js”的文件(或extensions.js或您拥有的文件)。 将您的插件文件与该一个主文件保持在一起。

  2. plugins.js将有一个名为“ pluginNames []”的数组,我们将在each()上进行迭代,然后将标签添加到每个插件的头部

    //设置当我们添加或删除插件文件时要更新的数组var pluginNames = [“ lettering”,“ fittext”,“ butterjam”等]; //每个插件一个脚本标签$ .each(pluginNames,function(){$('head')。append('');});

  3. 手动仅调用一个文件:

    <script src="js/plugins/plugins.js"></script>

我发现,即使所有插件都按应有的方式放到了head标签中,当您单击页面或刷新时,它们并不总是由浏览器运行。

我发现仅在PHP include中编写脚本标签会更可靠。 您只需编写一次,就和使用JavaScript调用插件一样多。


#28楼

我创建了一个函数,该函数将允许您使用与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  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: */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);}

#29楼

可以动态生成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");

#30楼

也许您可以使用在此页面上找到的此功能,

function include(filename){    var head = document.getElementsByTagName('head')[0];    var script = document.createElement('script');    script.src = filename;    script.type = 'text/javascript';    head.appendChild(script)}

#31楼

JavaScript的旧版本没有导入,包含或要求,因此已经开发了许多解决此问题的方法。

但是自2015年(ES6)起,JavaScript就拥有了标准,可以在Node.js中导入模块, 也支持该模块。

为了与旧版浏览器兼容,可以使用和/或工具。

ES6模块

自v8.5起,带有--experimental-modules标志的ECMAScript(ES6)模块已在Node.js中得到支持。 涉及的所有文件都必须具有.mjs扩展名。

// module.mjsexport function hello() {  return "Hello";}
// main.mjsimport { hello } from 'module'; // or './module'let val = hello();  // val is "Hello";

浏览器中的ECMAScript模块

Safari 10.1,Chrome 61,Firefox 60和Edge 16开始,浏览器已经支持直接加载ECMAScript模块(不需要像Webpack这样的工具)。请在查看当前支持。

// hello.mjsexport function hello(text) {  const div = document.createElement('div');  div.textContent = `Hello ${text}`;  document.body.appendChild(div);}

在了解更多

浏览器中的动态导入

动态导入使脚本可以根据需要加载其他脚本:

前往进一步了解

Node.js要求

仍然在Node.js中广泛使用的旧式导入模块是系统。

// mymodule.jsmodule.exports = {   hello: function() {      return "Hello";   }}
// server.jsconst myModule = require('./mymodule');let val = myModule.hello(); // val is "Hello"

JavaScript还有其他方法可以在不需要预处理的浏览器中包含外部JavaScript内容。

AJAX加载

您可以使用AJAX调用加载其他脚本,然后使用eval运行它。 这是最直接的方法,但是由于JavaScript沙箱安全模型,它仅限于您的域。 使用eval还打开了漏洞,黑客和安全问题的大门。

获取加载

像动态导入一样,您可以使用承诺通过库控制对脚本依赖项的执行顺序,从而通过fetch调用来加载一个或多个脚本:

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加载

库提供了加载功能:

$.getScript("my_lovely_script.js", function() {   alert("Script loaded but not necessarily executed.");});

动态脚本加载

您可以将带有脚本URL的脚本标签添加到HTML中。 为了避免jQuery的开销,这是一个理想的解决方案。

该脚本甚至可以驻留在其他服务器上。 此外,浏览器会评估代码。 可以将<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>标记,其中src属性设置为该函数作为第一个参数给出的URL。

在中讨论和说明了这两种解决方案。

检测何时执行脚本

现在,您必须知道一个大问题。 这样做意味着您需要远程加载代码 。 现代的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);

请注意,脚本可能在加载DOM之后或之前执行,具体取决于浏览器以及是否包含行脚本script.async = false; 。 ,有一篇对此进行了讨论。

源代码合并/预处理

如该答案的顶部所述,许多开发人员在其项目中使用了诸如Parcel,Webpack或Babel之类的构建/编译工具,从而允许他们使用即将到来的JavaScript语法,为较旧的浏览器提供向后兼容性,合并文件,缩小,执行代码拆分等

转载地址:http://qudnb.baihongyu.com/

你可能感兴趣的文章
ab压力测试
查看>>
SVN指定端口启动
查看>>
网站访问速度一般检查参数
查看>>
编译安装过程
查看>>
HTTP常见返回码信息
查看>>
WEB集群session处理方案
查看>>
JDK命令行(jps、jstat、jinfo、jmap、jhat、jstack、jstatd、hprof)与JConsole
查看>>
JAVA 对象访问: 句柄和指针
查看>>
秒杀系统优化思路
查看>>
dubbo 报错:java.lang.NoClassDefFoundError: org/I0Itec/zkclient/exception/ZkNoNodeException
查看>>
logback的使用和logback.xml详解
查看>>
Linux 快捷键
查看>>
JPA 联合主键配置
查看>>
ObjectAlreadyExistsException:Unable to store Job : '*', because one already exists with thi s ident
查看>>
mybatis & JPA 实体类型属性转换
查看>>
Git 中的 ~ 和 ^
查看>>
第一篇博客,给大家分享java、架构师、大数据、人工智能的学习路线,希望能够帮助到大家
查看>>
18级大数据专家,跟大家漫谈大数据平台架构,你能学到多少?上篇
查看>>
18级大数据专家,漫谈大数据平台安全风险与建设,值得学(下篇)
查看>>
阿里P8终于整理出:Nginx+jvm+MySQL+Docker+Spring实战技术文档
查看>>