不确定这是否是正确的方法,如果这甚至是一个“好”的问题,但我正在加载javscript作为插件样式架构的一部分,我有以下问题:
如果某个特定节点有插件引用,我想根据该插件的json描述提供的url加载该插件。描述将具有类似以下内容(或功能等同物):
{
"pluginSrc" : "http://mysite.com/plugins/1204.js",
"configData" :
{
"someData", "someValue",
"someMoreData", "etc"
}
}
当javascript加载时,我将有一个onload处理程序,它将检查窗口对象上是否存在函数名称,如果存在,则创建该函数的新实例并将其传递给配置数据(或多或少) ),这部分非常有效,只有少数例外。
有时候我没有引用我需要调用的函数的名称,也没有办法从json中获取它。什么是理想的,如果我可以告诉哪个函数被添加到脚本的onload回调上的window对象并创建该函数的实例。这可能吗?我只需要担心现代浏览器,特别是webkit。如果问题不清楚,我很乐意澄清,但是制作一个小提琴可能很困难,因为要编写很多代码来达到最小的例子。
我到目前为止所考虑的是在加载的脚本文件中创建某种全局变量,如
function MediaAnalytics(){};
var LoadedClass = MediaAnalytics;
只是在加载脚本时创建一个LoadedClass实例,但这并不是灵丹妙药,因为我不会一直在编写插件。
编辑:这些脚本很可能不是来自同一个域。
答案 0 :(得分:2)
您尚未指定加载脚本文件的方式。我希望你能在onload handler中获得脚本文本。
无论如何,我正在使用jQuery.getScript
解释如何执行此操作。在此,您将获得成功处理程序中的脚本文本data
。所以你可以使用它来获取加载的函数。
假设脚本文件 dynamic.js 包含
function MediaAnalytics(){};
使用getScript
$.getScript("dynamic.js", function (data, textStatus, jqxhr) {
var NewFunction;
eval("NewFunction = " + data);
alert(NewFunction.name); // here you will get alert showing MediaAnalytics
});
此处NewFunction
为MediaAnalytics
。
这将是脚本的第二次执行,因为getScript
在执行成功处理程序并将其添加到窗口对象后调用成功处理程序。您可以new NewFunction()
实例化。
如果您不喜欢使用eval
,另一种方法是使用RegEx查找函数的名称
$.getScript("dynamic.js", function (data, textStatus, jqxhr) {
alert(data.match(/function(.*)\(/));
});
这将提醒功能MediaAnalytics(。match
返回一个数组。可以从中检索该函数的名称。
您可以使用更好的RegExp来提取确切的函数名称并获取window对象的属性。
编辑:(没有jquery)
或者您可以将脚本作为文本加载,并在onload处理程序中添加到窗口作为脚本标记。即使插件脚本不是你的,你也可以使用你的技巧。
var dynamicjs = "function MediaAnalytics(){};"; // script loaded as text
var modified = "LoadedClass = " + dynamicjs;
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.textContent= modified; // innerText in some browsers
head.appendChild(script);
alert(LoadedClass); // LoadedClass is MediaAnalytics
答案 1 :(得分:1)
我建议让它需要在json中输入入口函数的名称。在我看来,这是最不可行的方式。
但是,您可以尝试的方法是迭代window
的所有属性。如果在加载脚本后在window
中找到新函数,则可以假设它是刚刚加载的函数。
像这样......
var windowMembers = [];
function loadScript() {
for(var m in window) {
windowMembers.push(m);
}
//load your new script
//some code here to load the script
//put an onload handler...
s.onload = function() {
for(var m in window) {
if(windowMembers.indexOf(m) == -1) {
//window[m] was added after the script loading began
//call it:
window[m]('blah blah');
}
}
}
}
为了安全起见,您可以选择检查新属性是否为函数,例如
if(typeof window[m] == 'function')