13

我正在为我玩的纸牌游戏开发套牌构建应用程序。我正在使用 localStorage 来保存和检索卡片组。它似乎在 Chrome 中运行良好,但在 Firefox 中运行不可靠。

在 FF 中,起初一切似乎都很好,套牌甚至在重新加载后仍然存在。但是,如果我添加第二个牌组并重新加载,它只会找到第一个牌组。如果我删除第一个牌组,它就再也找不到任何东西了。

所有本地存储交互都在 scripts/vault.js 中,我将在下面重现。难道我做错了什么?

vault = {};
vault.makeKey = function (s) {
    return "deck:" + s;
};
vault.friendlyName = function(s) {
    if (s.indexOf("deck:") === 0) {
        return s.substring(5);
    } else {
        return s;
    }
};
vault.store = function (deck, name) {
    if (!window.localStorage) {
        alert("This browser doesn't support local storage. You will be unable to save decks.");
        return;
    }
    var key = vault.makeKey(name);
    localStorage.setItem(key, deck.export());
};
vault.retrieve = function (key) {
    deck.import(localStorage[key]);
};
vault.getDecks = function () {
    var keys = Object.keys(localStorage),
        out = [],
        i,
        k,
        name = "";
    for (i = 0; i < keys.length; i++) {
        k = keys[i];
        name = vault.friendlyName(k);
        if (name !== k && localStorage[k]) {
            out.push({name: name, key: k});
        }
    }
    out.sort(function (a, b) {
        return a.name > b.name ? 1 : -1;
    });
    return out;
};
vault.deleteDeck = function (key) {
    localStorage.removeItem(key);
};

基本上,localStorage 中的键似乎在某些时候因为缺少更好的术语而被“冻结”;localStorage 在我操作它时会正常运行,但是一旦我刷新页面,它似乎就会恢复到它被冻结的任何状态。

4

5 回答 5

7

我曾多次遇到同样的问题,起初我没有注意到它无法读取 localStorage 的原因,但我想我找到了解决方案。

localStorage 操作都是同步的,不同的浏览器对它们如何处理它们有一定的怪癖。

在您的情况下,问题似乎是您试图在 DOM 准备好之前读取 localStorage 。我用 Firebug 尝试过,我在 vault.js 文件的开头添加了一个断点并重新加载页面,当代码中断时,我检查 dom-tab 并找到 localStorage 属性,它就在那里 - 存储的完整列表价值观。当我删除断点并重新加载页面时,加载页面后它们都消失了。

这可能是 Firefox 或其他浏览器中的错误,只是更快地初始化 localStorage。

因此,作为您的问题的解决方案:尝试在 DOM 准备好后从 localStorage 获取密钥。

于 2012-12-13T08:53:52.550 回答
5

虽然这是一篇旧文章,但我认为我的发现可能会有所帮助。我也遇到了同样的问题,所以我浏览了这篇文章,尝试了这个,这就是我注意到的,在 Firefox 中,如果你在 window.load 之前尝试用 localstorage 做任何事情(甚至是 localStorage.getItem),它会从它,你将一无所有。所以无论你想做什么设置或获取,都在 window.load 之后执行。

像这样的东西

$( window ).load(function() {
    //do whatever you want to do with localstorage
});

顺便说一句,在此之前,我试图在 document.ready 上对 localStorage 进行一些操作,但失败了。

于 2015-08-26T12:23:46.167 回答
1

在此处发布此内容以帮助可能正在经历我现在正在经历的任何人。

如果使用 Firefox,刷新页面后,您需要关闭并重新打开开发工具才能看到新的 localStorage 项目。

When the page refreshes, the localStorage items that were there before show. If you close and re-open the dev tools, you can see the new set. Any changes made from that point on (until the next refresh) will update live.

Definitely a Firefox dev tools bug.

I've reported the bug here: https://bugzilla.mozilla.org/show_bug.cgi?id=1706710

// Edit 5 minutes later I can't reproduce it now. I'm not sure but I think it might have been due to a Firefox update. It updated just as I'd finished writing the bug report. Did I really discover a bug in Firefox 87 that got fixed in Firefox 88 10 minutes before I updated?!! Will report back here if it re-occurs.

Animated gif of issue

于 2021-04-21T17:58:26.110 回答
0

我认为 jylauril 走在正确的轨道上。

我一直在玩延迟,并注意到一些奇怪的行为。

据我所知,似乎如果您在所有 JavaScript 完成执行之前触摸 localStorage,包括 JS 执行 setTimeout,localStorage 对于该网页浏览将显示为空白。例如:

$(window).load(function () {
    console.log("Waiting 10000ms", new Date());
    setTimeout(setDeckSelect, 10000);
});

Firebug 的控制台:

Waiting 10000ms Date {Thu Dec 13 2012 10:35:48 GMT-0500 (Eastern Standard Time)}
exec.js (line 191)
getDecks Date {Thu Dec 13 2012 10:35:58 GMT-0500 (Eastern Standard Time)}
vault.js (line 23)
>>> localStorage
0 items in Storage 

我想我可能会做一些事情,但到目前为止我的理论被证明是错误的。不过,我注意到了一件奇怪的事情。无论我等待多长时间,如果我先尝试查找套牌,它将失败并且本地存储将是空的:

>>> vault.getDecks()
[]
>>> localStorage
0 items in Storage 

但是如果我按照相反的顺序做这些......

>>> localStorage
8 items in Storage deck:dfs=
"{"identity":"MakingNews","cards":{}}", deck:ngrngfrn= "{"identity":"BuildingaBetterWorld","cards":{}}", deck:sdfgshsh= "{"identity":"MakingNews","cards":{}}", deck:sdfgdgdfg= "{"identity":"MakingNews","cards":{}}", deck:dfgdfgas= "{"identity":"EngineeringtheFuture","cards":{}}", deck:sdfsga= "{"identity":"MakingNews","cards":{}}", deck:gdgd= "{"identity":"MakingNews","cards":{}}", deck:gfsdfgsdfg= "{"identity":"BuildingaBetterWorld","cards":{}}"
>>> vault.getDecks()
[Object { name= "dfgdfgas",  key= "deck:dfgdfgas"}, Object { name= "dfs",  key= "deck:dfs"}, Object { name= "gdgd",  key= "deck:gdgd"}, Object { name= "gfsdfgsdfg",  key= "deck:gfsdfgsdfg"}, Object { name= "ngrngfrn",  key= "deck:ngrngfrn"}, Object { name= "sdfgdgdfg",  key= "deck:sdfgdgdfg"}, Object { name= "sdfgshsh",  key= "deck:sdfgshsh"}, Object { name= "sdfsga",  key= "deck:sdfsga"}]

如果我在函数中记录 localStorage,它也可以:

vault.getDecks = function () {
    console.log(localStorage);
    var keys = Object.keys(localStorage),
        out = [],
        i,
        k,
        name = "";
    for (i = 0; i < keys.length; i++) {
        k = keys[i];
        name = vault.friendlyName(k);
        if (name !== k && localStorage[k]) {
            out.push({name: name, key: k});
        }
    }
    out.sort(function (a, b) {
        return a.name > b.name ? 1 : -1;
    });
    return out;
};

有用。如果我取消它,虽然...

vault.getDecks = function () {
    // console.log(localStorage);
    void localStorage;
    var keys = Object.keys(localStorage),
        out = [],
        i,
        k,
        name = "";
    for (i = 0; i < keys.length; i++) {
        k = keys[i];
        name = vault.friendlyName(k);
        if (name !== k && localStorage[k]) {
            out.push({name: name, key: k});
        }
    }
    out.sort(function (a, b) {
        return a.name > b.name ? 1 : -1;
    });
    return out;
};

这没用。如果我删除 void 关键字并仅将 localStorage 作为语句,它也不起作用。

我不知道为什么,但 console.log(localstorage) 似乎确实解决了这个问题,我可以随时调用 localStorage。

实在是太诡异了。

编辑:我找到了一个更好的解决方案。调用 localStorage 的 'length' 属性也可以。

vault.getDecks = function () {
    //Weird hack to make FF load localStorage correctly...
    localStorage.length;
    var keys = Object.keys(localStorage),
        out = [],
        i,
        k,
        name = "";
    for (i = 0; i < keys.length; i++) {
        k = keys[i];
        name = vault.friendlyName(k);
        if (name !== k && localStorage[k]) {
            out.push({name: name, key: k});
        }
    }
    out.sort(function (a, b) {
        return a.name > b.name ? 1 : -1;
    });
    return out;
};

这更好一点,因为它不记录任何东西......

于 2012-12-13T15:52:47.923 回答
-2

• 确保localStorage 数据在所有html 页面中始终可用: o 域(本地上下文)必须相同。o 确保在所有 Html 文件中保持 << script >> 标签相同, o(仅限 Firefox)确保 onPageLoad 在所有 JavaScript 文件中保持相同(添加在 html 文件中),即确保向 PageLoadEvent 添加相同的函数.

于 2013-09-26T15:58:52.977 回答