当前位置:  开发笔记 > 编程语言 > 正文

如何在另一个JavaScript文件中包含JavaScript文件?

如何解决《如何在另一个JavaScript文件中包含JavaScript文件?》经验,为你挑选了41个好方法。

JavaScript中是否存在类似于@importCSS的内容,允许您在另一个JavaScript文件中包含JavaScript文件?



1> e-satis..:

旧版本的JavaScript没有导入,包含或要求,因此开发了许多不同的方法来解决这个问题.

但自2015年(ES6)以来,JavaScript已经有了ES6模块标准来导入Node.js中的模块,大多数现代浏览器也支持这些模块.

为了与旧版浏览器兼容,可以使用构建和/或转换工具.

ES6模块

自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模块

自 Safari 10.1,Chrome 61,Firefox 60和Edge 16 以来,浏览器已经支持直接加载ECMAScript模块(不需要像Webpack这样的工具).检查caniuse的当前支持.


// 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/

浏览器中的动态导入

动态导入允许脚本根据需要加载其他脚本:


有关详情,请访问https://developers.google.com/web/updates/2017/11/dynamic-import

Node.js需要

仍然在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加载

您可以使用AJAX调用加载其他脚本,然后使用eval它来运行它.这是最简单的方法,但由于JavaScript沙箱安全模型,它仅限于您的域.使用eval也打开了通往错误,黑客和安全问题的大门.

获取加载

与Dynamic Imports一样,您可以fetch使用promises 加载一个或多个脚本,使用Promise来控制脚本依赖项的执行顺序,使用Fetch Inject库:

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

在jQuery的库提供加载功能在同一行:

$.getScript("my_lovely_script.js", function() {
   alert("Script loaded but not necessarily executed.");
});
动态脚本加载

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

该脚本甚至可以驻留在不同的服务器上.此外,浏览器评估代码.该');

但是,此方法也存在一个问题:如果导入的JavaScript文件中发生错误,Firebug(以及Firefox错误控制台和Chrome开发人员工具)也会错误地报告其位置,如果您使用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('');
                import_js_imported.push(script);
            }
        }
    });

})(jQuery);

所以你需要做的就是导入JavaScript:

$.import_js('/path_to_project/scripts/somefunctions.js');

我也在Example中做了一个简单的测试.

它包括一个main.js主HTML文件,然后在脚本中main.js使用$.import_js()导入称为一个附加文件included.js,它定义了这个功能:

function hello()
{
    alert("Hello world!");
}

在包括之后included.js,hello()调用该函数,您就会收到警报.

(这个答案是对e-satisf'评论的回应).


@juanpastas - 使用[`jQuery.getScript`](http://api.jquery.com/jQuery.getScript/),这样你就不必担心编写插件......
嗯,根据[本文](http://www.html5rocks.com/en/tutorials/speed/script-loading/),将`script`元素附加到`head`会导致它以异步方式运行,除非`async`专门设置为`false`.

4> Ariel..:

另一种方式,在我看来更清晰,是制作同步Ajax请求而不是使用

要点:http://gist.github.com/284442.


jrburke将此写为RequireJS.Github:http://requirejs.org/docs/requirements.html

11> Dan Dascales..:

以下是Facebook为普遍使用的Like按钮做广告的一般化版本:



12> Venu immadi..:

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

document.write('');

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

$.getScript("another_script.js");


不会document.write删除其他一切?

13> Calmarius..:

您还可以使用PHP组装脚本:

档案main.js.php:



// Main JavaScript code goes here


听起来重点是将这一切保留在前端的javascript中

14> Dmitry Sheik..:

此处显示的大多数解决方案都意味着动态加载.我正在搜索一个编译器,它将所有依赖的文件组合成一个输出文件.与Less/Sass预处理器相同,处理CSS @importat-rule.由于我没有找到这种类似的东西,我写了一个简单的工具来解决这个问题.

所以这里是编译器,https://github.com/dsheiko/jsic,它可以$import("file-path")安全地替换所请求的文件内容.这是相应的Grunt插件:https://github.com/dsheiko/grunt-jsic.

在jQuery master分支上,他们只是简单地将原子源文件连接成一个intro.jsouttro.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

并获得组合文件

建立/ main.js

var foo = function() {
    return {
          prop: "",
          method: function(){}
    }
};


从这篇文章开始,我提出了更好的解决方案 - CommonJS模块编译器 - https://github.com/dsheiko/cjsc因此,您可以简单地编写CommonJs或NodeJs模块并相互访问,同时将它们保持在隔离的范围内.好处:不需要多个影响性能的HTTP请求您不需要手动包装模块代码 - 它是编译器的责任(因此更好的源代码可读性)您不需要任何外部库它与UMD兼容 - 和NodeJs模块(例如,您可以将jQuery,Backbone作为模块解决而无需触及其代码)

15> Adem İlhan..:

如果您要加载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文件中包含脚本时,您需要小心.订单应如下所示:


  
  
  
  



16> tggagne..:

这应该做:

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


@MattDMo"有人说这很糟糕"并不是真正的争论.
@MattDMo我完全清楚他是谁,但他是一个人,而不是一个神.
`eval`是它的错误.来自[Crockford](http://javascript.crockford.com/code.html),"eval"是邪恶的."eval"函数是JavaScript中最被滥用的特性.避免它.`eval`有别名.不要使用`Function`构造函数.不要将字符串传递给`setTimeout`或`setInterval`." 如果您还没有阅读他的"JavaScript:The Good Parts",那么现在就去做吧.你不会后悔的.
@emodendroket我认为你不知道谁是[Douglas Crockford](http://en.wikipedia.org/wiki/Douglas_Crockford).
@tggagne:我可以做些什么来让它适用于跨域?*(从http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js`)加载脚本

17> 小智..:

或者不是在运行时包括在上载之前使用脚本连接.

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

也可以看看:

介绍Sprockets:JavaScript依赖关系管理和连接



18> Turnerj..:

如果您正在使用Web Workers并希望在worker的范围内包含其他脚本,则提供有关向head标记添加脚本等的其他答案将不适合您.

幸运的是,Web Workers有自己的importScripts功能,这是Web Worker范围内的全局功能,是浏览器本身的原生功能,因为它是规范的一部分.

或者,作为对您的问题突出显示的第二高投票答案,RequireJS还可以处理包含Web Worker中的脚本(可能调用importScripts自身,但具有一些其他有用的功能).



19> Manohar Redd..:

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

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

为此,我做了如下:

以正确的顺序加载HTML文件中的JavaScript代码,首先是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文件的变量可以在第二个JavaScript文件中自动访问.

这节省了我的一天.我希望这有帮助.



20> Isaac Gregso..:

@import实现CSS-像JavaScript语法进口可能使用的工具,如通过其特殊的混合.mix文件类型(见这里).我想应用程序只是在内部使用上述方法之一,但我不知道.

从文件的混合文档.mix:

混合文件只是带有.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无任何关联.我看到一个.mixJavaScript文件在运行中(在其中一个Mixture样板中)并且有点困惑("你能做到这一点吗?"我想到了自己)时遇到了这个问题.然后我意识到这是一个特定于应用程序的文件类型(有点令人失望,同意).然而,认为这些知识可能对其他人有所帮助.

更新:混合物现在是免费的(离线).

更新:混合物现已停产.旧的混合物发布仍然可用



21> Christopher ..:

我通常的方法是:

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> Dmitry Sheik..:

用现代语言来说就是这样

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



23> 小智..:
var js = document.createElement("script");

js.type = "text/javascript";
js.src = jsFilePath;

document.body.appendChild(js);


这是最简单的代码,但是[在`body`尚不存在的情况下会失败](http://stackoverflow.com/questions/950087/include-a-javascript-file-in-another-javascript -file/31282622#31282622)或无法修改.此外,它有助于解释答案.

24> stamat..:

我编写了一个简单的模块,可以自动执行在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);
};



25> KthProg..:

虽然这些答案很棒,但是存在一个简单的"解决方案",因为脚本加载已存在,它将覆盖大多数人的99.999%的用例.只需在需要它的脚本之前包含所需的脚本.对于大多数项目,确定需要哪些脚本以及按什么顺序排列并不需要很长时间.



    
        
        
    
    

如果script2需要script1,这确实是做这样的事情的绝对最简单的方法.我很惊讶没有人提出这个问题,因为这是几乎每一个案例中最明显和最简单的答案.



26> rgb_life..:

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

    设置一个名为"plugins.js"(或extensions.js或者你有什么)的文件.将插件文件与一个主文件保持在一起.

    plugins.js将有一个名为"pluginNames []"的数组,我们将遍历每个(),然后为每个插件追加一个标记到头部

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

    手动调用你头脑中的一个文件:

我发现即使所有的插件都按照它们应该的方式放入头标签,但当你点击页面或刷新时,它们并不总是被浏览器运行.

我发现在PHP包中编写脚本标记更可靠.您只需编写一次,这与使用JavaScript调用插件一样重要.



27> Vicky Gonsal..:

此脚本将JavaScript文件添加到任何其他

mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有