账户在一个窗口下多tab页切换商户问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/a1390033590/article/details/86594815

背景:一个账号下有多个商户,且登录状态后端保存,当前账号信息存在localstorage中

第一个想法:一个事件storge当localstorage里的值发生变化时触发,(可以不在当前页面触发)

          window.addEventListener('storage', (e) => {
              // console.log('google');
    // 事件对象 其中e.key是发生变化的localStorage里的key e.oldValue变化之前的值,e.newValue变化之后的值
              // console.log(e);
              this.merchantName =                             JSON.parse(localStorage.getItem('userinfo')).merchantName;
              console.log(this.merchantName);
              localStorage.setItem('null_item', null);
            if ((e.key === 'userinfo')) {
              console.log(e);
              if (!e.newValue) return;
              const oldValue = JSON.parse(e.oldValue);
              const newValue = JSON.parse( );
              if (oldValue.merchantName !== newValue.merchantName) {
                this.dialogVisible = true;
                this.merchantName = newValue.merchantName;
              }
            }
          });

在谷歌浏览器是没有问题的,然而奇葩的IE(10,11)都不行,它监听不到localstorage里值得变化,感觉IE中,localstorage是不共享的,和sessionstorage差不多。所以这个事件pass

第二个,找到了visibilitychange事件,窗口下切换tab页时触发,document.visibilityState值有两个,visible和hidden

新值和旧值,旧值我取的是sessionstorage里的值,之前会把当前账户在session和local里都存一份。

document.addEventListener('visibilitychange', () => {
          if (document.visibilityState === 'visible') {
              const oldValue = JSON.parse(sessionStorage.getItem('userinfo')).merchantName;
              const newValue = JSON.parse(localStorage.getItem('userinfo')).merchantName;;
              if (oldValue !== newValue) {
                this.dialogVisible = true;
              }
          }
        });

不知道有没有发现,对的,IE又有了兼容问题,因为我的newValue又取了localstorage里的值,他不是最新值,所以没有变化,好悲伤。想了好久,忽然想到,当前状态后端也存了一份,所以代码:

document.addEventListener('visibilitychange', () => {
          if (document.visibilityState === 'visible') {
            api.get('/rest/current').then((data) => {
              const oldValue = JSON.parse(sessionStorage.getItem('userinfo')).merchantName;
              this.merchantName = data.data.merchantName;
              if (oldValue !== this.merchantName) {
                this.dialogVisible = true;
              }
            });
          }
        });

有没有很完美,然而这不完美,我又发现个一个很恐怖的bug,visibilitychange里代码会执行很多很多遍,因为有请求,所以更恐怖,一个接口会发送好多遍,我找了很久很久,想到了节流阀,然而真的没有用,连规律都没有找到,马上就要绝望的时候,问了我们老大,老大不愧是老大,人家找了一会就发现了问题(冒泡or捕获)addEventListener,对的,就是在最后加一个false。

  • true - 事件句柄在捕获阶段执行
  • false- false- 默认。事件句柄在冒泡阶段执行

 完整代码:

 document.addEventListener('visibilitychange', () => {
          if (document.visibilityState === 'visible') {
            api.get('/rest/current').then((data) => {
              const oldValue = JSON.parse(sessionStorage.getItem('userinfo')).merchantName;
              this.merchantName = data.data.merchantName;
              if (oldValue !== this.merchantName) {
                this.dialogVisible = true;
              }
            });
          }
        }, false);

这样就解决了,哦,对了,还有一个问题,如果不是在一个窗口下,visibilitychange是不会触发的

猜你喜欢

转载自blog.csdn.net/a1390033590/article/details/86594815
今日推荐