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

时间:2012-07-03 14:04:35

标签: javascript jquery file dynamic external

我需要从另一个“.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中的值而不加载整个外部文件。

这个让我难倒了几个小时,所以任何想法都会受到高度赞赏。

6 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

您希望在使用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
 });
});

答案 2 :(得分:0)

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

$.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代码的最佳工具;例如,上面的示例不会解析具有嵌套{}块的函数,这些块可能存在于相关代码中。

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

答案 3 :(得分:0)

我不确定这是一个好主意,但你可以创建一个iframe并在其'window'对象中评估该文件,以避免大多数不需要的副作用(假设它不会尝试访问其父级)。然后,您可以通过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。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

有可能在Web Workers的帮助下。你可以在一个孤立的环境中运行你想要注入的脚本,这样就不会弄乱你当前的页面。

正如你所说,setAppLogo可能在"test/testApp_1.js"内是全球性的,所以我会依赖这个陈述。

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

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

然后,在worker(worker.js)中,你可以使用特殊函数importScriptsdocs),它允许在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的更多信息以及可能存在的缺陷。