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


当前回答

下面是使用HTML导入的浏览器(而不是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 輸入將減少

HTML 进口减少,有利于 ES6 模块,您应该使用 ES6 模块。

其他回答

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

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

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

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 => {} );

也许这里还有另一种方式!

在 Node.js 中,你可以这样做,就像下面的代码一样!

主持人JS

    module.exports = {
      log: function(string) {
        if(console) console.log(string);
      }
      mylog: function(){
        console.log('just for log test!');
      }
    }

主.js

    const mylog = require('./sub');

    mylog.log('Hurray, it works! :)');
    mylog.mylog();

雷夫斯

HTTP://requirejs.org/docs/node.html

另一种方式,在我看来是更清洁的,是做一个同步的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);
        }
    });
}

然后你可以在你的代码中使用它,因为你通常会使用一个包括:

require("/scripts/subscript.js");

并能够在下列行中从所需脚本中呼叫一个函数:

subscript.doSomethingCool(); 

与 $.getScript 和实际上任何其他解决方案需要一个呼叫回复,当加载完成时的问题是,如果你有多个文件使用它,并依赖对方,你已经没有办法知道什么时候所有的脚本被加载(一旦它们被纳入多个文件)。

文件3JS

var f3obj = "file3";

// Define other stuff

文件2JS:

var f2obj = "file2";
$.getScript("file3.js", function(){

    alert(f3obj);

    // Use anything defined in file3.
});

此分類上一篇: 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...
});

您可以尝试使用 $.when 检查一系列丢失的对象,但现在您正在做这一点在每个文件和文件2 将被视为加载,一旦 $.when 执行,而不是当呼叫回复执行,所以文件1 仍然继续执行之前文件3 被加载,这真的仍然有相同的问题。

我喜欢延长jQuery的想法,但显然你不需要。

在呼叫document.writeln之前,它检查以确保脚本已经没有被加载,通过评估所有脚本元素。

而不是这个方法,你可以尝试修改 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;
    }
});

使用:

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