9

我有一个单页应用程序,它使用 Knockout.js 进行数据绑定,使用 Sammy.js 来路由客户端(基于哈希)的 URL。

但是,我在 Internet Explorer 中看到了一个奇怪的问题:有时链接在单击时会更改浏览器地址栏中的 URL,但相应的 Sammy 路由不会执行。

它不会每次都发生(但我可以始终如一地重现错误),它只发生在 IE10 中(Chrome 每次都可以正常工作)。它似乎也与 Knockout 有关,因为一组硬编码链接不会出现相同的问题。

为了说明,我已经剥离了所有内容,除了重新创建问题的最低限度并创建了两个 jsbin 示例:

示例 1(带有 Knockout):http: //jsbin.com/aretis/2/

要查看问题,请打开上面的链接并单击“Record #1”,然后单击“Baz”,然后再次单击“Record #1”。记录 1 的 URL 将出现在地址栏中,但该记录的路由不会附加到列表中。

示例 2(没有淘汰赛):http: //jsbin.com/amivoq/1/

在此示例中,我有一个记录链接的静态列表,而不是数据绑定列表。单击任何链接(以任何顺序)将导致该路线被附加到列表中(应该如此)。

提醒这些必须在 IE 中运行才能重现问题。

有任何想法吗?

4

1 回答 1

2

根据我上面的评论,我通过捕获 window.hashchange 事件并自己解析 URL 来解决这个问题。这是我真正使用的 Sammy.js 的唯一部分,我没有任何运气来追踪实际问题。希望这会对其他人有所帮助。

我做的第一件事是绑定 hashchange 事件:

$(function () {
    $(window).on("hashchange", HandleUrl);

    // Call our URL handler to deal with any initial URL given to us.
    HandleUrl();
}

这将调用以下 URL 解析器:

function HandleUrl() {
    var hash = location.hash;

    if (hash.indexOf("#Account") >= 0) {
        var splitParts = hash.split("/");

        if (splitParts.length >= 2) {
            ShowLoadingBox();
            ShowAccountDetailFromId(splitParts[1]);
        }
    } else if (hash.indexOf("#Contact") >= 0) {
        var splitParts = hash.split("/");

        if (splitParts.length >= 2) {
            ShowLoadingBox();
            ShowContactDetailFromId(splitParts[1]);
        }
    } else if (hash.indexOf("#ThingsToDo") >= 0) {
        SwitchToPanel("navPanelThingsToDo");
    } else if (hash.indexOf("#ThingsIveDone") >= 0) {
        SwitchToPanel("navPanelThingsIveDone");
    } else if (hash.indexOf("#Reports") >= 0) {
        SwitchToPanel("navPanelReports");
    } else {
        SwitchToPanel("navPanelMyAccounts");
    }
}

ShowAccountDetailFromId()类似的功能SwitchToPanel()只是显示和填充(使用 Ajax 对 Web 服务的调用)适当的<div>. 这可能是一种完全幼稚的方法,但它是有效的(即您可以为 URL 添加书签、后退按钮和浏览器历史记录等)。对于未回答的“答案”,我深表歉意。

于 2013-10-03T16:43:57.040 回答