建设银行网站不能登录,江西旅游网站建设方案,杭州杭州网站建设,继续教育网站怎么做不了作业前言 前段时间在做一个基于 psd 模板生成图片的应用#xff0c;其中重要的功能就是打开编辑器页面来设计出图。但是有个问题#xff0c;每当我点击一个模板#xff0c;就会新开一个浏览器页签。现代浏览器是以空间换时间的运行思路来提高效率#xff0c;这就导致了内存开销… 前言 前段时间在做一个基于 psd 模板生成图片的应用其中重要的功能就是打开编辑器页面来设计出图。但是有个问题每当我点击一个模板就会新开一个浏览器页签。现代浏览器是以空间换时间的运行思路来提高效率这就导致了内存开销会越来越大也曾想过postmessage来解决这个问题但是呢 postmessage 是跨域广播说白了我 post 的消息任意页签都能 listen 到不友好。最近刷抖音时看到了一个前端教学视频其中就讲到了网页音乐单开的实现方式核心原理**BroadcastChannel**。 技术原理 BroadcastChannel 接口代理了一个命名频道可以让指定 origin 下的任意 browsing context 来订阅它。它允许同源的不同浏览器窗口Tab 页frame 或者 iframe 下的不同文档之间相互通信。通过触发一个 message 事件消息可以广播到所有监听了该频道的 BroadcastChannel 对象。 创建或者加入频道 客户端通过构造函数传入频道名称即可创建或加入频道。如果当前不存在此命名的频道就会初始化并创建。 // 创建或加入频道
const channel new BroadcastChannel(editor_channel); 发送消息 基于刚才创建或加入的频道实例调用 postMessage 方法发送消息。可以使用 BroadcastChannel.postMessage() 发送一条任意 Object 类型的消息给所有同源下监听了该频道的所有浏览器上下文。消息以 message 事件的形式发送给每一个绑定到该频道的广播频道。 channel.postMessage(message: any); 接受消息 通过监听 message 事件即可接收到同频道发送的任意消息。 channel.addEventListener(message, ({data: any}) {console.log(data);
})
// 或者
channel.onmessage ({data: any}) {console.log(data);
} 异常处理 通过监听 messageerror 事件即可捕获异常。 qh_channel.addEventListener(messageerror, e) {console.error(e);
})
// 或者
qh_channel.onmessagerror (e) {console.error(e);
} 断开连接 调用 close() 方法即可断开对象和基础通道之间的链接。 qh_channel.close() 实现 原理搞清楚了那么接下来就是实战了。 先上效果图 图中使用了2个受控页面目的是想验证多个页面能够被统一控制而且咱也的确控制不了用户的某些操作。 封装 Channel 类 const editorList [];
/*** description: 页面通信类* param {String} channelName channel名称* param {String} page 实例化channel的页面名称* param {Boolean} isEditor 是否是编辑器* param {String} editorName 编辑器页面名称* param {Function} onmessage 接收到消息的回调* return {Channel} channel实例*/
export default class Channel {constructor({ channelName, page, isEditor false, editorName, onmessage }) {if (!page) throw new Error(page is required);if (!isEditor !editorName) throw new Error(editorName is required);this.__uuid__ Math.random().toString(36).substr(2);this.isEditor isEditor; // 是否是编辑器this.editorName editorName; // 编辑器页面名称this.page page; // 实例化channel的页面名称this.name channelName ?? qh_channel; // channel名称this.channel new BroadcastChannel(this.name);this.addEvent(onmessage);this.load(); // 告诉其他页面我初始化完了}addEvent(onmessage) {this.channel.onmessage ({ data: { type, page, data, uuid } }) {if (!this.isEditor) {if (page this.editorName) {// 如果是编辑器页面发送的消息this.updateEditor(type, uuid);}} else if (type load page ! this.page) {// 其他页面加载时告诉知我已经存在了this.load();}if (onmessage) {onmessage({ type, page, data });}};}// 如果用户手动打开了多个编辑器需要更新编辑器列表updateEditor(type, uuid) {const index editorList.indexOf(uuid);if (type load) {if (index -1) {editorList.push(uuid);}} else if (type unload) {if (index ! -1) {editorList.splice(index, 1);}}}postMessage(data) {if (!!editorList.length || this.isEditor) {const newData { page: this.page, uuid: this.__uuid__, ...JSON.parse(JSON.stringify(data)) };this.channel.postMessage(newData);return true;}return false;}load() {this.channel.postMessage({ type: load, uuid: this.__uuid__, page: this.page });}unload() {this.channel.postMessage({ type: unload, uuid: this.__uuid__, page: this.page });this.channel.onmessage null;this.channel.close();}close() {}
} 主控页面逻辑 在主控页面引入并实例化 Channel 类。其中 page 和 editorName 必须填写。 import Channel from /utils/channel;const editorChannel new Channel({page: template_index,editorName: editor_index,onmessage: ({ type, page, data }) {if (type confirm page editor_index) {Modal.confirm({title: 警告,icon: createVNode(ExclamationCircleOutlined),content: 模板还未保存确认替换,onOk() {editorChannel.postMessage({ type: force_data, data });},});}},
});
window.onunload () {editorChannel.unload();
};
onUnmounted(() {editorChannel.unload();
});// 点击事件
const itemClick (node) {if (!editorChannel.postMessage({ type: data, data: node })) {const rt router.resolve(/editor/${node.id});safeOpen(rt.href);}
}; 前边提到了 safeOpen 实现方案也很简单具体为什么要 safeOpen 请自行 google 。 window.open(url, target, noreferrer,noopener); 受控页面逻辑 受控页面同样引入并实例化 Channel 类。page 必须填写并且要标记 isEditor: true 明确告知这是编辑器页面这样 Channel 类就知道在 onmessage 时知道如何处理逻辑了。 import Channel from /utils/channel;const editorChannel new Channel({page: editor_index,isEditor: true,onmessage: ({ type, data }) {if (type data) {if (dirty) {// 有修改在主控页面弹窗提醒editorChannel.postMessage({ type: confirm, data });} else {// 无修改window.location.href /editor/${data.id};}} else if (type force_data) {// 强制更新数据window.location.href /editor/${data.id};}},
});
window.onunload () {editorChannel.unload();
};
onUnmounted(() {editorChannel.unload();
}); 其实呢代码量也不多核心就是 Channel 类记录编辑器广播通信的 __uuid__ 这里之所以使用数组记录是因为用户的确可以通过 url 地址强制多开那咱也没办法只能一并记录更新当主控页面想要打开新的编辑器时优先调用 postMessage 方法根据其返回结果判断编辑器是否存在如果存在就触发受控页面更新路由并加载如果不存在就打开新页签。 总结 BroadcastChannel 是一个非常简单的 API 内部包含了跨上下文同源通信的接口。它没有定义消息传输协议故不同上下文中的不同文档需要自己实现。目前来看兼容性方面也基本没有问题。 - END - 关于奇舞团 奇舞团是 360 集团最大的大前端团队代表集团参与 W3C 和 ECMA 会员TC39工作。奇舞团非常重视人才培养有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。
文章转载自: http://www.morning.mqtzd.cn.gov.cn.mqtzd.cn http://www.morning.gwwtm.cn.gov.cn.gwwtm.cn http://www.morning.zxhhy.cn.gov.cn.zxhhy.cn http://www.morning.hrhwn.cn.gov.cn.hrhwn.cn http://www.morning.hhrpy.cn.gov.cn.hhrpy.cn http://www.morning.kggxj.cn.gov.cn.kggxj.cn http://www.morning.qqrlz.cn.gov.cn.qqrlz.cn http://www.morning.xlxmy.cn.gov.cn.xlxmy.cn http://www.morning.lnwdh.cn.gov.cn.lnwdh.cn http://www.morning.wqfzx.cn.gov.cn.wqfzx.cn http://www.morning.bklkt.cn.gov.cn.bklkt.cn http://www.morning.bwxph.cn.gov.cn.bwxph.cn http://www.morning.tcfhs.cn.gov.cn.tcfhs.cn http://www.morning.gglhj.cn.gov.cn.gglhj.cn http://www.morning.c7623.cn.gov.cn.c7623.cn http://www.morning.pfnrj.cn.gov.cn.pfnrj.cn http://www.morning.yhxhq.cn.gov.cn.yhxhq.cn http://www.morning.rkxdp.cn.gov.cn.rkxdp.cn http://www.morning.ctlbf.cn.gov.cn.ctlbf.cn http://www.morning.qfgwx.cn.gov.cn.qfgwx.cn http://www.morning.qkdbz.cn.gov.cn.qkdbz.cn http://www.morning.rjfr.cn.gov.cn.rjfr.cn http://www.morning.nzfyx.cn.gov.cn.nzfyx.cn http://www.morning.fkdts.cn.gov.cn.fkdts.cn http://www.morning.lszjq.cn.gov.cn.lszjq.cn http://www.morning.kztts.cn.gov.cn.kztts.cn http://www.morning.bkxnp.cn.gov.cn.bkxnp.cn http://www.morning.mwjwy.cn.gov.cn.mwjwy.cn http://www.morning.whpsl.cn.gov.cn.whpsl.cn http://www.morning.rcbdn.cn.gov.cn.rcbdn.cn http://www.morning.mbpzw.cn.gov.cn.mbpzw.cn http://www.morning.knmp.cn.gov.cn.knmp.cn http://www.morning.mnkz.cn.gov.cn.mnkz.cn http://www.morning.shuanga.com.cn.gov.cn.shuanga.com.cn http://www.morning.rxfbf.cn.gov.cn.rxfbf.cn http://www.morning.ddtdy.cn.gov.cn.ddtdy.cn http://www.morning.rgdcf.cn.gov.cn.rgdcf.cn http://www.morning.ylklr.cn.gov.cn.ylklr.cn http://www.morning.sogou66.cn.gov.cn.sogou66.cn http://www.morning.whnps.cn.gov.cn.whnps.cn http://www.morning.mzpd.cn.gov.cn.mzpd.cn http://www.morning.cgstn.cn.gov.cn.cgstn.cn http://www.morning.wgcng.cn.gov.cn.wgcng.cn http://www.morning.xylxm.cn.gov.cn.xylxm.cn http://www.morning.kxscs.cn.gov.cn.kxscs.cn http://www.morning.nfmlt.cn.gov.cn.nfmlt.cn http://www.morning.xtqr.cn.gov.cn.xtqr.cn http://www.morning.wxrbl.cn.gov.cn.wxrbl.cn http://www.morning.ryxdf.cn.gov.cn.ryxdf.cn http://www.morning.kgphd.cn.gov.cn.kgphd.cn http://www.morning.zrlwl.cn.gov.cn.zrlwl.cn http://www.morning.dyzbt.cn.gov.cn.dyzbt.cn http://www.morning.rqpgk.cn.gov.cn.rqpgk.cn http://www.morning.xgxbr.cn.gov.cn.xgxbr.cn http://www.morning.hbxnb.cn.gov.cn.hbxnb.cn http://www.morning.hrpjx.cn.gov.cn.hrpjx.cn http://www.morning.wdqhg.cn.gov.cn.wdqhg.cn http://www.morning.fkfyn.cn.gov.cn.fkfyn.cn http://www.morning.jtwck.cn.gov.cn.jtwck.cn http://www.morning.shnqh.cn.gov.cn.shnqh.cn http://www.morning.lqlc.cn.gov.cn.lqlc.cn http://www.morning.jfwbr.cn.gov.cn.jfwbr.cn http://www.morning.yfcbf.cn.gov.cn.yfcbf.cn http://www.morning.jqkjr.cn.gov.cn.jqkjr.cn http://www.morning.njftk.cn.gov.cn.njftk.cn http://www.morning.zrpys.cn.gov.cn.zrpys.cn http://www.morning.fylqz.cn.gov.cn.fylqz.cn http://www.morning.phgz.cn.gov.cn.phgz.cn http://www.morning.fnwny.cn.gov.cn.fnwny.cn http://www.morning.qdbcd.cn.gov.cn.qdbcd.cn http://www.morning.bdypl.cn.gov.cn.bdypl.cn http://www.morning.fgwzl.cn.gov.cn.fgwzl.cn http://www.morning.wdykx.cn.gov.cn.wdykx.cn http://www.morning.lffgs.cn.gov.cn.lffgs.cn http://www.morning.njfgl.cn.gov.cn.njfgl.cn http://www.morning.clndl.cn.gov.cn.clndl.cn http://www.morning.lsmgl.cn.gov.cn.lsmgl.cn http://www.morning.jgzmr.cn.gov.cn.jgzmr.cn http://www.morning.pqktp.cn.gov.cn.pqktp.cn http://www.morning.slmbg.cn.gov.cn.slmbg.cn