通过切换文件覆盖JS功​​能

时间:2012-05-09 14:49:04

标签: javascript ajax user-interface function-overriding

我知道,一旦加载了一个脚本,你就可以从页面中删除<script>元素,变量/函数仍然存在。

假设我有两个版本的函数,处理UI,用户可以根据偏好进行选择。

整个页面都是基于AJAX的。理想情况下,除非用户明确地完成,否则不应重新加载,因此调用location.reload()根本不可能。

我的想法是:

<script type="text/javascript" src="ui1.js" id="uiscript"></script>

然后简单地改变:

document.getElementById('uiscript').src = ...;

两个文件的格式均为:

var ui = function(...) {
    ...
};

所以我的问题是,两个来源之间的切换是否会可靠地改变功能?即使脚本被缓存了?我会更好地添加cachebusting查询字符串吗?或者我应该完全抛弃这个想法并寻找其他东西,比如在回调中重写函数而不是改变脚本的来源?

有关此类事情的任何其他建议吗?

4 个答案:

答案 0 :(得分:3)

为什么不使用该函数的引用?这里有一些伪代码:

function func1() { /* Do stuff one way */}
function func2() { /* Do stuff the other way */}
var ui = func1;

ui(some_param);

function myCallback() {
  // overwrite ui
  ui = func2;
  ui(some_param); // now calls func2
}

这只是一个简单的例子。在现实世界中,您可以使用Objects将功能组合在一起。

也许你可以使用像inject

这样的JavaScript的依赖注入框架

答案 1 :(得分:0)

基本上,你要做的只是不好的做法 - 尝试用另一个版本覆盖一个版本的JS。不要这样做。

如果你有两个版本的函数,那么给它们不同的函数名称并将变量设置为活动函数,然后使用该变量执行当前函数,如下所示:

function drawMethodOne() {}
function drawmethodTwo() {}
var currentDrawMethod = drawMethodOne;

然后,在您的代码中,您将使用currentDrawMethod

currentDrawMethod();

作为对您的问题的更具体的答案,javscript不会卸载以前加载的函数定义。加载更多重新定义现有函数名称的脚本只会将新函数分配给该现有名称,使前一个函数的代码不可访问。因此,可以通过加载重新定义该函数名称的新javascript来替换以前的函数定义,但这通常是一种不好的做法,我可以想到许多情况下调试会非常痛苦。

答案 2 :(得分:0)

作为一个快速测试,Chrome只是在更改源代码时甚至没有尝试为我加载第二个脚本。添加一个新的脚本元素似乎拉入第二个js文件并覆盖该函数。如果这两个函数永远不会改变,您可能想要缓存它们,只需将“ui”变量重新分配给您需要的任何函数。我同意上面的不良做法评论,但我不知道你的用例。

答案 3 :(得分:0)

坦率地说,我不能对这种行为说多少 - 就我所能想到的而言,它只是不可预测和依赖于实现。更好的想法是使用以下内容:

// usage: call skinHandler.setSkin({/* a skin object */)
// now having set the skin, call the skin's functions using skinHandler.skin.MyFunc();
app.skinHandler = function() {
    var oldSkin = null;
    this.skin = null;
    // call this after loading the skin object.
    this.setSkin = function(skin) {
        oldSkin = this.currentSkin;
        this.skin = skin;
    };
};

皮肤对象将包含ui所需的所有代码,并且因皮肤而异。现在,要使用它,您需要将每个皮肤/主题文件的功能包装在单独的对象中。