谈谈StorageEvent

更新日期: 2019-06-03阅读: 3k标签: 应用
纷纷红紫已成尘,布谷声中夏令新。夹路桑麻行不尽,始知身是太平人。 ——宋.陆游 《初夏绝句》

我们在开发多Tab应用时候,常常会遇到多个Tab状态同步的问题。

想象如下场景:用户主界面,显示用户购物车内待结算的商品总数。此时,用户可能打开多个Tab。当用户添加新商品到购物车的时候,需要更新购物车的数量。


此时,当前页面需要向服务器发起请求,在得到添加成功响应的时候,可以更新用户界面。为了兼顾体验和可靠性,如果确信添加成功概率比较高的时候,也可以先更新界面,当多数返回错误的时候,可以给用户界面做状态回滚。为了下次展示方便,我们还会把这个数据写到LocalStorage里面。用户再次打开时候,可以优先从localStorage中取值。

当前页面解决了,那么如果同时打开多个Tab该如何解决呢?这里使用StorageEvent可能是一种代价较小的解决方案。


StorageEvent是什么呢?

  1. 是一种Event,可以通过标准的Event监听器操作。

  2. 当storage变化时候,事件会被派发到所有同域下的其他页面。

  3. 触发变化的当前页面,没有事件派发。

这里有一个简单的示例可以展示这个api的用法。

const STORAGE_KEY = "cartlist"

const getStorage = () => {
    try {
        let rets = window.localStorage.getItem(STORAGE_KEY)

        if (rets === null) {
            return []
        }
        return JSON.parse(rets)
    }
    catch(e){
        return []
    }
}

const addCart = (value) => {
    let rets = getStorage()

    rets.push(value)

    window.localStorage.setItem(STORAGE_KEY, JSON.stringify(rets))

    return rets
}

const minusCart = (value) => {
    let rets = getStorage()
    let idx = rets.indexOf(value)

    if (idx !== -1){
        rets.splice(idx, 1)
        window.localStorage.setItem(STORAGE_KEY, JSON.stringify(rets))
    }


    return rets
}

const render = () => {
    let rets = getStorage()

    if (rets.length){
        $("#num").html(rets.length).show()
    }
    else {
        $("#num").hide()
    }

    $(".list li").each((i,el) => {
        if (rets.includes(i)){
            $(el).find("a:nth-child(1)").css("visibility", "hidden")
            $(el).find("a:nth-child(2)").css("visibility", "visible")

        }
        else {
            $(el).find("a:nth-child(1)").css("visibility", "visible")
            $(el).find("a:nth-child(2)").css("visibility", "hidden")

        }
    })
}

$(".list a").on("click", (e)=> {
    let opIdx = $(e.target).parent().find("a").index(e.target)
    let line = $(e.target).parent().parent()
    let idx = $(".list li").index(line)

    opIdx === 0 ? addCart(idx) : minusCart(idx)

    render()

    return false
})

window.addEventListener('storage', (e) => {
    render()
})

render()

其中,下面这行代码是实现的关键:

window.addEventListener('storage', (e) => {
    render()
})

当我们注释掉这个语句,我们的页面同步就不能运行了。

读者可以打开多个Tab并观察页面的变化 https://jsbin.com/radekilosu/1/edit?html,css,js,output 。

实际上,这个事件e上还带有很多信息,方便编程时,对于事件做精确的控制。

字段含义
key发生变化的storageKey
newValue变换后新值
oldValue变换前原值
storageArea相关的变化对象
url触发变化的URL,如果是frameset内,则是触发帧的URL

上述各值都是只读的。

还有一点没有解决掉,就是触发storage变化的本页面,不能接收这个值,这个一般情况下是没问题。当然,为了一致性,我们可以自行new一个事件,在发生时候主动触发它。

此时我们可以包装一个新的Storage对象:

var Storage = {
    setItem : function(k,v){
      localStorage.setItem(k,v);
    },
    removeItem : function(k){
      localStorage.removeItem(k);
    },
    clear: function (){},
    getItem: function(k)
}

此时,我们再包装一个函数

function dispatchMe(key, oldval, newval, url, storage){
    var se = document.createEvent("StorageEvent");
    se.initStorageEvent('storage', false, false, key, oldval, newval, url, storage);
    window.dispatchEvent(se);
}

此时,我们只需要再setItem、removeItem、clear中获取对应的值,并手动调用一dispatchMe,同时把和localStorage打交道的地方改为调用我们的新对象即可。

来自:奇舞周刊
本文作者 刘观宇,360 奇舞团高级前端工程师、技术经理,W3C CSS 工作组成员。  


链接: https://www.fly63.com/article/detial/3524

使用html+css+js实现简易计算器

今天带大家做一个网页版的一个精美的计算器,使用的计算器可以实现标准计算器的功能,题目:计算器的实现,技术:html+css+js,使用html+css+js实现简易计算器,开启你的计算之旅吧。效果图如下,复制即可使用

C/S,B/S应用的区别

C/S(Client/Server) :客户端/服务器结构,其中客户端和服务器端都是独立的计算机;B/S(Browser/Server):浏览器/服务器结构,B/S是特殊的一种C/S结构,是对C/S的改进和变化,B/S是基于应用层http协议的web

浅谈单页应用和多页应用

多页面应用:每次页面跳转,后台都会返回一个新的HTML文档,就是多页面应用。单页应用:用vue写的项目是单页应用,刷新页面会请求一个HTML文件,切换页面的时候,并不会发起新的请求一个HTML文件,只是页面内容发生了变化

flutter打开第三方应用的实现?

1.flutter开发者网站下载url_launcher插件;在 pubspec.yaml 文件中添加依赖;安装:flutter pub get;导入;_launchURL、_openMapApp为自定义方法名 可以根据自己的场景自定义名称

使用Flask构建一个Web应用

Flask是一个使用Python编写的轻量级Web应用框架。以管理员身份,打开命令提示符窗口,输入下面命令py -3 -m pip install flask

PWA渐进式Web应用:你需要知道的一切

你是否正处于选择 App 开发技术的两难境地?如今,渐进式 Web 应用程序需求旺盛。知道这是为什么吗 ?下面让我们来详细的梳理一下。移动电话用户的增长促使在线企业重新考虑对移动应用的优化

多数程序员难以简单的方式开发应用?

心理学中有一篇相当古老、但又非常重要的论文,题为《魔法数字七(上下浮动二):人类信息处理能力中的一些限制》。这篇文章衡量了大脑处理信息的极限,并给出了一个具体的数字:人脑可以同时容纳五到九个概念

使用typescript构建Vue应用

使用typescript构建Vue应用和使用js一样,都是通过vue-cli去初始化并创建一个vue项目,只不过使用typescript构建的时候要在脚手架问卷操作的时候勾选上typescript选项。使用typescript构建的Vue项目发生了一些变化:

BFC的作用及其应用

BFC就是块级格式化上下文,是页面盒模型布局中的一种 CSS 渲染模式,相当于一个独立的容器,里面的元素和外部的元素相互不影响。

如何加快 Node.js 应用的启动速度?

我们平时在开发部署 Node.js 应用的过程中,对于应用进程启动的耗时很少有人会关注,大多数的应用 5 分钟左右就可以启动完成,这个过程中会涉及到和集团很多系统的交互,这个耗时看起来也没有什么问题。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!