乐趣区

关于javascript:关于在A页面操作B页面刷新数据这件事

这里是忽然怠惰的 Zhuo,继续更新文档中。

需要

“小 Z,你说能不能做到在 A 页面新增一个数据之后,B 页面也同步刷新,呈现方才新增的那个数据呢?”PO 对着我说。

“能够是能够,然而 …”我正筹备说。

“我就晓得你行,我这个版本有一个交互优化点,你来看看。”PO 满脸坏笑。

“….”

“纯前端能够实现,然而有局限。B 页面只能由 A 页面关上的,而且须要 B 页面反对一些性能,所以 B 页面最好是咱们零碎外部的。”我说

“这也行吧”PO

成果

剖析

计划比照

计划 长处 毛病 备注
通过回调函数 简略粗犷 1. 须要主页面全局注册函数,不利于扩大
2. 依赖 opener,一旦主页面将它设置为空则获取不到内容了
监听 localStorage 满足根本需要 须要两个页面都满足同源策略条件
WebSocket 服务 1. 不仅能跨窗口,还能够跨浏览器,甚至跨账号 1. 须要服务端参加
2. 所有的页面都会收到事件
message 事件 1. 不须要页面同源
2. 只有约定好传递的信息,即便不同零碎也能通信
1. 不同零碎之间须要约定好传递的内容 采纳

通过回调函数

  1. 首先,在主页面的 window 上注册一个全局函数 callback
  2. 接着,从零碎中关上一个子页面 window.open(href, '_blank')
  3. 最初,通过子页面 window.opener.window.callback() 进行函数调用

先讲一下 window.opener 返回关上以后窗口的那个窗口的援用,例如:在 window A 中关上了 window B,B.opener 返回 A

这个计划的实现是利用了 window.opener 的个性,间接入侵到主页面中去做一个函数的调用。(都间接能获取到 window 了,想做点什么不行)

注:这个会导致一些平安的问题,如果零碎中跳转到一些不牢靠的第三方地址,那么它能够通过 window.opener 间接批改零碎的内容,解决这个问题只有把它的 opener 设置成空。

let page = window.open(href, '_blank')
page.opener = null

监听 localStorage

  1. 一个窗口更新 localStorage,另一个窗口监听 window 对象的 storage 事件,来实现通信。
// 子页面设置
localStorage.setItem('page-event', Date.now())

// 主页面监听
window.addEventListener('storage', function (e) {// 去做一些其余的事})

注: 该形式须要两个窗口满足同源策略的条件。

WebSocket 服务

借助后盾起一个 socket 服务,让所有须要进行跨窗口通信的页面都开启一个 WebSocket 服务监听这个地址,利用 send 进行播送,其余页面监听该事件,这个计划不仅能跨窗口,还能跨浏览器。

let ws = new WebSocket('ws://localhost:3000/')
ws.onopen = function (event) {
      // 或者把此办法注册到其余事件中,即可与其余服务器通信
      ws.send({now : Date.now()}) // 通过服务器直达音讯
    
    ws.onmessage = function (event) {
          // 生产音讯
          console.log(event.data)
    }
}

message 事件

  1. 首先,是从零碎中关上一个子页面 window.open(href, '_blank'):MDN;
  2. 接着,在主页面监听 message 事件:MDN;
  3. 最初,从子页面 postMessage 数据到主页面。

利用 message 实现会有一些限度和平安的问题,在 MDN 下面曾经有欠缺的解决办法了,大家间接参考它下面的就行了。

残缺实现:


<script lang="ts" setup>
import {ElButton} from 'element-plus';
import {ref} from 'vue';

let pageHandle = ref<Window>();
let message = ref<string>();

const openPage = () => {
    pageHandle.value =
        window.open('http://localhost:3000/', '_blank') ?? undefined;

    window?.addEventListener('message', event => {
        // 过滤掉非同域名下的信息
        if (event.origin === location.origin) {message.value = event.data;}
    });
};
const sendMessage = () => {
    window.postMessage(` 我已出仓,感觉良好。工夫:${Date.now()}`,
        location.href
    );
};
</script>

明天这个班就上到这里。

退出移动版