13

私がプレイするカードゲームのデッキ構築アプリケーションに取り組んでいます。デッキの保存と取得に localStorage を使用しています。Chrome では問題なく動作しているように見えますが、Firefox では動作が不安定です。

FF では、最初はすべてがうまく機能しているように見え、デッキはリロード後も持続します。ただし、2 番目のデッキを追加してリロードすると、最初のデッキしか見つかりません。最初のデッキを削除すると、何も見つかりません。

ローカル ストレージとのやりとりはすべて 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 に答える
0

jylaurilは正しい方向に進んでいると思います。

私は遅れて遊んでいて、いくつかの奇妙な振る舞いに気づいています。

私の知る限り、JSがsetTimeoutを実行するなど、すべてのJavaScriptの実行が完了する前にlocalStorageに触れると、そのページビューでは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 

私は何かに取り組んでいるかもしれないと思ったが、これまでの私の理論は間違っていることが証明された。しかし、私が気付いた奇妙なことが1つあります。どれだけ待つかに関係なく、最初にデッキを調べようとすると失敗し、ローカルストレージは空になります。

>>> 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 << script >> タグがすべての Html ファイルで同一であることを確認してください。 o (Firefox のみ) すべての JavaScript ファイル (html ファイル内に追加) で onPageLoad が同一であることを確認してください。つまり、同じ関数を PageLoadEvent に追加してください。 .

于 2013-09-26T15:58:52.977 に答える