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

在传统的多页面应用中,用户使用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 事件无法使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值