【问题标题】:storing a variable in localStorage is too slow在 localStorage 中存储变量太慢
【发布时间】:2014-02-04 01:10:25
【问题描述】:

我有两个 jQuery 移动页面(#list 和 #show)。 #list 页面上有几个具有不同 ID 的项目。如果我点击第 5 项,第 5 号 ID 将存储在 localStorage 中,我将被重定向到页面#show

现在的问题: 将 ID 存储在 localStorage 中有效,但下一页显示的不是第 5 项,而是显示一个旧项目,之前在 localStorage 中。

#list 页面中的脚本

localStorage.setItem("garageID", $(this).attr('id'));                           
window.location.replace("#show");

【问题讨论】:

  • 这听起来不像是“太慢”的问题。 (旁注:您始终可以使用this.id 代替$(this).attr('id'),并且总是更快。)
  • 为什么不用changePage?
  • 大家好。我知道这不是一个“太慢”的问题,但我不知道如何描述:) @Omar。我以为 window.location.replace 是一样的?
  • changePage 功能不只是切换页面,它更新历史,传输数据...等
  • 好的,如果我有一个不想在历史记录中看到的页面,我可以使用 window.location.replace .. 对吗?

标签: javascript jquery html jquery-mobile


【解决方案1】:

我也遇到了这个问题(而不是在移动设备上:在 Chromium/linux 上)。

由于似乎没有基于回调的 API,我用超时“修复”了它,以“防止”在 setItem 操作完成之前关闭页面:

localStorage.setItem(name, value);                           
setTimeout(function(){
     // change location
}, 50);

0 的超时可能就足够了,但由于我没有找到任何规范(它可能在错误的范围内)并且问题没有始终如一地重现,所以我没有抓住任何机会。如果你愿意,你可以循环测试:

function setLocalStorageAndLeave(name, value, newLocation){
    value = value.toString(); // to prevent infinite loops
    localStorage.setItem(name, value);
    (function one(){
         if (localStorage.getItem(name) === value) {
            window.location = newLocation;
         } else {
            setTimeout(one, 30);
         }
    })();
}

但我不明白localStorage.getItem 返回正确值这一事实如何保证它确实以永久方式写入,因为没有可中断行为的规范,我不知道the following part of the spec 是否可以合法解释为意味着允许浏览器在离开页面时忘记在磁盘上转储:

本规范不要求上述方法等到 数据已物理写入磁盘。只有在什么方面保持一致 访问相同底层键/值列表的不同脚本 需要对看到。

在您的具体情况下,解决方案可能是简单地滚动到具有该给定名称的元素以避免更改页面。

关于假定错误的说明:

我没有找到也没有填写任何错误报告,因为我发现它很难重现。在我在 Chromium/linux 上观察到的情况下,它发生在 delete 操作中。

【讨论】:

  • 如果你已经做了这样的解决方案,我至少会经常检查变量是否在这段时间内写入,然后继续。否则你有一个丑陋的 setTimeout 并且仍然不知道变量是否在 localStorage 中。
  • @MichaelKunst 测试不能保证任何事情:localStorage 的本地版本可能会更新,但硬盘不会更新。
  • @MichaelKunst 它丑陋的,因此“固定”周围的引号。
  • 我已经测试了您的解决方案,但它不起作用。超时时间也为 500。只有当我刷新页面时,它才能工作
【解决方案2】:

免责声明:此解决方案不是官方的,仅针对演示进行了测试,未针对生产进行测试。

您可以使用$.mobile.changePage("target", { data: "anything" }); 在页面之间传递数据。但是,它仅在 targetURL(又名 单页模型)时有效。

尽管如此,您仍然可以在页面之间传递 数据 - 即使您使用的是多页面模型 - 但您需要手动检索它。

当页面改变时,它会经历几个阶段,其中之一是pagebeforechange。该事件带有两个对象 eventdata。后一个对象包含与您要从中移动的页面和您要去的页面相关的所有详细信息。

由于$.mobile.changePage() 会忽略在多页模型 上传递的参数,您需要通过$.mobile.changePage("#", { options }) 将自己的属性 推送到data.options 对象中,然后检索当pagebeforechange 被触发时。这样您就不需要 localstorage 也不需要回调或setTimeout

  1. 第一步:

    在更改页面时传递数据。使用唯一的 property 以免与 jQM 冲突。我用过stuff

    /* jQM <= v1.3.2 */
    $.mobile.changePage("#page", { stuff: "id-123" });
    
    /* jQM >= v1.4.0 */
    $.mobile.pageContainer.pagecontainer("change", "#page", { stuff: "id-123" });
    
  2. 第二步:

    在您要移动到的页面上触发pagebeforechange 时检索数据,在您的情况下为#show

    $(document).on("pagebeforechange", function (event, data) {
    
      /* check if page to be shown is #show */
      if (data.toPage[0].id == "show") {
    
        /* retrieve .stuff from data.options object */
        var stuff = data.options.stuff;
    
        /* returns id-123 */
        console.log(stuff);
      }
    });
    

Demo

【讨论】:

    猜你喜欢
    • 2018-08-13
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    • 2013-06-03
    • 1970-01-01
    • 2013-06-19
    • 2015-08-18
    相关资源
    最近更新 更多