从一个 Javascript 文件中从另一个 Javascript 文件调用函数

Call a function in one Javascript file from another Javascript file?

本文关键字:文件 Javascript 另一个 函数 调用 一个      更新时间:2023-09-26

我需要从另一个".js"文件中调用外部".js"文件中的函数,而无需引用<head>标记中的外部文件。

我知道可以动态添加一个外部".js"文件,以允许访问该文件,我可以这样做......

var AppFile = "test/testApp_1.js"; 
var NewScript=document.createElement('script');
var headID = document.getElementsByTagName("head")[0]; 
NewScript.src = AppFile;
headID.appendChild(NewScript);

然而。。。

这对我来说没有用,因为外部文件必须是运行启动过程的独立文件......

$(document).ready(function()
{...}

因此,动态添加完整文件会产生不必要的影响。此外,我无法在 <head> 标签中预先引用外部文件,因为它需要动态。因此,这个外部文件"test/testApp_1.js"包含一个返回字符串变量的函数......

function setAppLogo(){
 var LogoFile = "test/TestApp_1_Logo.png";
 return LogoFile;
}       

我需要访问此函数,或者我可以将字符串作为全局变量存储在外部文件中......无论哪种方式都很好,我只需要访问LogoFile中的值而无需加载整个外部文件。

这个已经让我难倒了几个小时,所以任何想法将不胜感激。

您可能会受益于某种包含全局变量/值的app.js文件,您希望从很多地方使用这些文件/值。 你应该在每个页面上都包含这个.js文件(如果你想聪明并提高性能,可以缩小它/与其他js连接它)。 通常,这些全局变量应该附加到您创建的某些对象,例如带有变量/函数的var APPNAME = { };,这些变量/函数将在许多地方使用。

一旦你有了这个,那么你想要加载的外部'.js'文件,以及你当前所在的文件,都可以访问全局 APPNAME 变量及其所有属性/函数,并根据需要使用它们。 这可能是使javascript更加模块化和可分离的更好方法。 希望这有帮助。

您希望在使用 ajax 加载 jQuery 后加载文件,然后在成功的 ajax 函数中运行相关脚本。

参见jQuery的getScript函数:http://api.jquery.com/jQuery.getScript/

$(document).ready(function(){
 $.getScript("http://domain.com/ajax/test.js", function(data, textStatus, jqxhr) {
    console.log(data); //data returned
    console.log(textStatus); //success
    console.log(jqxhr.status); //200
    console.log('Load was performed.');
    //run your second script executable code here
 });
});

可以通过 XHR 加载整个脚本(例如 jQuery 中的 $.get),然后解析它,也许使用正则表达式,以提取所需的部分:

$.get('pathtoscript.js', function(scriptBody) {
    var regex = /function's+setUpLogo'(')'s*'{[^}]+}/g;
    alert(scriptBody.match(regex)[0]); // supposed to output a function called
                                       // 'setUpLogo' from the script, if the 
                                       // function does not have {} blocks inside
});

然而,应当指出,这种做法极有可能造成维修障碍。正则表达式不是解析 JavaScript 代码的最佳工具;例如,上面的例子不会解析带有嵌套 {} 块的函数,这些块很可能存在于相关代码中。

可能建议找到问题的服务器端解决方案,例如在将页面发送到浏览器之前添加必要的脚本路径或其部分。

我不确定这是一个好主意,但您可以创建一个 iframe 并在其"窗口"对象内评估文件以避免大多数不需要的副作用(假设它不尝试访问其父级)。然后,您可以通过 iframe 的窗口对象访问您想要的任何函数/变量。

例:

function loadSomeJsInAFrame(url,cb) {
        jQuery.get(url,function(res) {
            iframe = jQuery('<iframe></iframe>').hide().appendTo(document.body);
            iframe[0].contentWindow.eval(res);
        if(cb) cb(iframe[0].contentWindow);
    },'text');
}
loadSomeJsInAFrame('test/testApp_1.js',function(frameWindow) {
    console.log(frameWindow.setAppLogo());
    jQuery(frameWindow.frameElement).remove();
});

这不能保证文件中的sript不会弄乱您的文档,但如果它来自受信任的来源,则不太可能。

另外,不要忘记在从iframe获得所需内容后将其删除。

好的,感谢大家的所有输入,但我认为我尝试做的事情目前是不可能的,即从另一个文件访问函数而不加载该文件。但是,我已经找到了解决问题的方法。我现在向我的服务器查询可用的应用程序列表,然后使用此列表在 UI 中动态构建应用程序。然后选择应用程序后,我可以调用该文件及其中的函数。它有点复杂,但它的动态,具有良好的性能,并且可以工作。再次感谢您的头脑风暴!;)

在 Web Workers 的帮助下,这也许是可能的。您将能够在有点隔离的环境中运行您想要注入的脚本,因此它不会弄乱您当前的页面。

正如你所说,setAppLogo有可能在"test/testApp_1.js"内是全球性的,所以我将依靠这个说法。

在原始脚本中,您应该创建一个工作线程,该工作线程引用工作线程脚本文件 + 侦听来自工作线程的消息:

var worker = new Worker('worker.js');
worker.onmessage = function (e) {
    // ....
};

然后,在worker(worker.js)中,你可以使用特殊的函数importScripts(docs),它允许在worker中加载外部脚本,worker还可以看到这些脚本的全局变量。此外,worker中还有一个postMessage函数,可以将自定义消息发送回原始脚本,而原始脚本又监听这些消息(worker.onmessage)。worker.js代码 :

importScripts('test/testApp_1.js');
// "setAppLogo" is now available to worker as it is global in 'test/testApp_1.js'
// use Worker API to send message back to original script
postMessage(setAppLogo());

当它调用时,你会得到监听器中setAppLogo的结果:

worker.onmessage = function (e) {
    console.log(e.data); // "test/TestApp_1_Logo.png"
};

这个例子是非常基本的,你应该阅读更多关于 Web Workers API 和可能的陷阱。