4

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

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

整个页面大量基于 AJAX。理想情况下,除非用户明确执行,否则它永远不应该重新加载,因此根本不可能调用location.reload()

我的想法是这样的:

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

然后简单地改变:

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

这两个文件的格式为:

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

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

关于这样的事情还有其他建议吗?

4

4 回答 4

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
}

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

也许你可以使用像注入这样的 JavaScript 依赖注入框架

于 2012-05-09T14:58:46.780 回答
0

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

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

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

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

currentDrawMethod();

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

于 2012-05-09T14:59:07.177 回答
0

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

于 2012-05-09T15:00:36.773 回答
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;
    };
};

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

于 2012-05-09T15:02:18.620 回答