我如何在另一个JavaScript文件中添加一个JavaScript文件,类似于CSS中的 @import?


当前回答

如果你想要它在纯粹的JavaScript,你可以使用document.write。

document.write('<script src="myscript.js" type="text/javascript"></script>');

如果您使用 jQuery 图书馆,您可以使用 $.getScript 方法。

$.getScript("another_script.js");

其他回答

是的,有......

在 ES6 中,我们可以将部分或整个JavaScript文件导出并导入到另一个文件中。

但等待,ES6不支持所有浏览器,所以你需要通过 babel.js 使用它,例如...

所以你创建一个类如下:

class Person {
  constructor(name) {
    this.name = name;
  }

  build() {
    return new Person(this);
  }
}

module.exports = Person;

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 存在: 脚本与页面剩余的同步执行(脚本将执行,而页面继续播放) 如果 async 没有存在,并且 defer 存在: 脚本在页面完成播放时执行 如果没有 async 或 defer 存在: 脚本被捕并执行 imme

如果你发现有两个或多个脚本在被召唤时占据相同功能,我们不能同时包含它们,我们需要通过用户选择进行动态操作。

在 jQuery 中的另一个文件使用 $.getScript 工作,因为脚本不会默认隐藏。

HTML

<select class="choice">
  <option value="script1" selected>Script-1</option>
  <option value="script2">Script-2</option>
</select>

雅各布斯

$(".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 ) {
    // Execute here
  });
}

// script2
function script2() {
  $.getScript($.url2, function( data, textStatus, jqxhr ) {
    // Execute here
  });
}

上面的功能工作顺利,如果您只加载一个脚本,或者您不关心多个脚本的加载顺序. 如果您有某些脚本依赖于其他,您需要使用承诺来指定加载顺序. 背后的原因是JavaScript加载资源如脚本和图像无同步。

因此,这里是另一个动态LoadScript的版本,保证下载命令:

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

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 等顺序加载。

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

要显示未经处理的承诺拒绝(错误加载脚本等),将此未经处理的拒绝事件听器放在代码的顶部:

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

我基本上做如下,创建一个新的元素,并添加它来主导:

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

在现代语言中,如果脚本已经加载了,则会:

function loadJs( url ){
  return new Promise(( resolve, reject ) => {
    if (document.querySelector( `head > script[ src = "${url}" ]`) !== null ){
        console.warn( `script already loaded: ${url}` );
        resolve();
    }
    const script = document.createElement( "script" );
    script.src = url;
    script.onload = resolve;
    script.onerror = function( reason ){
        // This can be useful for your error-handling code
        reason.message = `error trying to load script ${url}`;
        reject( reason );
    };
    document.head.appendChild( script );
  });
}

使用(async/await):

try { await loadJs("https://.../script.js"); }
catch(error) { console.log(error); }

await loadJs( "https://.../script.js" ).catch( err => {} );

使用(承诺):

loadJs( "https://.../script.js" ).then( res => {} ).catch( err => {} );