前端跨页面通信问题及解决方案(window.onstorage)

  • Post author:
  • Post category:其他


在传统的多页面应用中,用户使用tab标签打开了2个页面A和 B,当用户在A页面做了某个操作后,需要在B页面去触发执行某个对应事件。

举个栗子!

当用户在A页面填写并提交了一个表单。一旦表单提交成功,B页面需要自动显示表单内容。

使用

onstorage

方法,语法如下:

window.onstorage = function(e){...};

A页面的html

<div class="main-content">
    <div class="content-bar">
        <label for="userName">用户名:</label>
        <input type="text" id="userName" />
    
        <label for="age">年龄:</label>
        <input type="text" id="userAge" />
    </div>

    <div class="submint-bar">
        <button id="btnSubmit">提交</button>
    </div>
</div>

A页面 javascript

(() => {
    const elm = document.querySelector('#btnSubmit');
    elm.addEventListener('click', () => {
        // 获取表单数据并组合成一个数据对象
        let userName = document.querySelector('#userName').value,
            userAge = document.querySelector('#userAge').value,
            userInfo = {};

        if(!userName || !userAge) throw new Error('用户名和年龄不能为空');
        userInfo = { userName, userAge };
        
        // 将表单数据存到localStorage
        (typeof userInfo === 'object') 
            ? localStorage.setItem('storage', JSON.stringify(userInfo))
            : localStorage.setItem('storage', userInfo)
    });
})();

当用户填写完表单数据后,点击表单提交按钮 <button id=”btnSubmit”>提交</button>。

B页面的html

<div id="userInfo">
    
</div>
(() => {
    // 当A页面进行将本地存储时,触发B页面的onstorage方法;
    window.onstorage = function(e) {
        // 当A页面进行localStorage存储动作时,
        // 一旦存储完成,就会触发 window.onstorage() 方法。
    }
})();

完善B页面的JavaScript

(() => {
    // 当A页面进行将本地存储时,触发B页面的onstorage方法;
    let onstorage = function(e) {
        const userInfo = JSON.parse(e.newValue);
        const elm = document.querySelector('#userInfo')
        const fragment = document.createDocumentFragment();
        let node = null;
        let textNode = null;
        
        // 当变量 userInfo 是一个非空对象时
        (Object.prototype.toString.call(userInfo) === '[object Object]') 
            && (JSON.stringify(userInfo) !== '{}') 
            && Object.entries(userInfo).forEach((item, index) => {
            let properName = index === 0 ? '用户名' : '用户年龄'

            //创建一个node元素节点
            node = document.createElement('div')
            //创建一个node文本节点
            textNode = document.createTextNode(`${properName} = ${item[1]}`);
            //向node元素节点插入文本节点
            node.appendChild(textNode);
            //将node节点加入文档碎片(可以理解为虚拟DOM)
            fragment.appendChild(node);
        });
        // 循环结束后,将文档碎片插入DOM解构
        elm.appendChild(fragment);
    }
})();

此时,如果用户在A页面填写用户名:张三,年龄:18,提交后,

B页面就会出现:“用户名 = 小鱼,用户年龄 = 18”,html结构如下。

<div id="userInfo">
    <div>用户名 = 小鱼</div>
    <div>用户年龄 = 18</div>
</div>


*注!

1、浏览器在同一个域名下面的通过tab打开多个页面,当其中的一个页面的

localStorage改变

数据时,其他所有页面(B)的

window.onstorage

事件会被触发,而原始页面(A)并不触发

window.onstorage

事件。

2、只有

localStorage

可以触发

window.onstorage

事件,

sessionStorage不能触发

3、如果修改的值未发生改变,

window.onstorage

事件将不会触发 。

4、

window.onstorage

事件的浏览器支持效果好、API直观、操作简单。


缺点:部分浏览器隐身模式下,无法设置 localStorage。如safari,这样也就导致 onstrage 事件无法使用。



版权声明:本文为haoduoyu2099原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。