这里是忽然怠惰的 Zhuo,继续更新文档中。
需要
“小 Z,你说能不能做到在 A 页面新增一个数据之后,B 页面也同步刷新,呈现方才新增的那个数据呢?”PO 对着我说。
“能够是能够,然而 …”我正筹备说。
“我就晓得你行,我这个版本有一个交互优化点,你来看看。”PO 满脸坏笑。
“….”
“纯前端能够实现,然而有局限。B 页面只能由 A 页面关上的,而且须要 B 页面反对一些性能,所以 B 页面最好是咱们零碎外部的。”我说
“这也行吧”PO
成果
剖析
计划比照
计划 | 长处 | 毛病 | 备注 |
---|---|---|---|
通过回调函数 | 简略粗犷 | 1. 须要主页面全局注册函数,不利于扩大 2. 依赖 opener,一旦主页面将它设置为空则获取不到内容了 |
|
监听 localStorage |
满足根本需要 | 须要两个页面都满足同源策略条件 | |
WebSocket 服务 |
1. 不仅能跨窗口,还能够跨浏览器,甚至跨账号 | 1. 须要服务端参加 2. 所有的页面都会收到事件 |
|
message 事件 |
1. 不须要页面同源 2. 只有约定好传递的信息,即便不同零碎也能通信 |
1. 不同零碎之间须要约定好传递的内容 | 采纳 |
通过回调函数
- 首先,在主页面的 window 上注册一个全局函数
callback
; - 接着,从零碎中关上一个子页面
window.open(href, '_blank')
; - 最初,通过子页面
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
- 一个窗口更新
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
事件
- 首先,是从零碎中关上一个子页面
window.open(href, '_blank')
:MDN; - 接着,在主页面监听
message
事件:MDN; - 最初,从子页面
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>
明天这个班就上到这里。