档案网站建设经验整合营销公司排名
今天下午是一个非常痛苦的,想要实现一个功能:
父页面打开了一个新的页面(浏览器打开一个新的窗口),并在子页面提交数据之后,父页面的数据要同步更新。
难点:父页面是一个表格列表,有分页功能,更新数据之后,要保证页面还在原来的页面。
把子页面关闭之后返回原来的页面,更新对应数据。
简单说下最开始使用的方法,以及最终采用方法,中间尝试的方法暂时略过不谈了…
-
关闭当前窗口,强制刷新父页面
window.opener.location.reload();刷新父窗口 window.close();关闭当前窗口
上面两行代码网上推荐的比较多的,但是存在问题:
- window.opener意思是当前浏览器窗口的打开者,就是指父窗口。window.opener.location.reload()强制刷新了父窗口,也就是说,并不会保留父窗口原有的状态。
- window.close();只是单纯的将当前窗口关闭了,焦点并不一定会回到父窗口。(若是打开子窗口的时候,同时打开了其它网页的窗口,关闭子窗口,焦点可能回到你刚刚浏览过的窗口)
在实现这个功能的时候,尝试过诸如以下方法:
-
利用浏览器缓存父窗口参数,带参数刷新父窗口。
-
在子组件内调用父窗口的方法(因为不是直接父子组件的关系,还尝试利用中间组件实现子组件内调用父组件方法)。
-
在子组件内调用父窗口的方法(第二个方法没有成功,又尝试了将父组件方法暴露给window对象也没成功)。
-
…
-
成功解决问题
尝试了很多方法多没有成功,我又回到了起点,开始分析问题。
分析之后发现其实这个大问题可以分为两个小问题:
- 子窗口关闭后,焦点需要回到父窗口;
- 焦点回到父窗口后,父窗口需要带状态刷新页面。
那我就一一攻破,首先是第一个小问题,查到了一些资料之后,发现可以实现,代码如下:
-
子窗口关闭,焦点回到父窗口
我的功能都是基于vue项目的,所以代码结构都是基于vue
// 父窗口文件中 mounted() {// 设置当前窗口的名字,便于当某些窗口页面关闭时,跳回当前窗口window.name = 'home'; }// 子窗口文件中,可以写在某一个方法中 // 回到父窗口home页面 window.open(window.opener.location.href, window.opener.name); // 关闭当前浏览器 window.close();
第一步实现了,我能正确的回到父窗口了,但是父窗口的对应数据并没有刷新。
-
父窗口需要带状态刷新页面
父窗口文件代码如下:
methods: {handleVisiable(e){if(e.target.visibilityState === 'visible') {this.initData();}} }, mounted() {// 设置监听,当本页面打开的新页面关闭时,触发事件document.addEventListener('visibilitychange', this.handleVisiable); },
这样便实现了对应的功能。
正当我准备提交测试时,客户的需求变了,计划赶不上变化呀!!,客户要求:
在页面关闭的时候,先倒计时5秒,之后再关闭。
我查了一些资料,发现浏览器有保护机制,除了用户直接点击的链接或按钮跳转,浏览器不会拦截,其它浏览器都会拦截。
也就是说:
设置一个定时器,定时器时间结束后,触发方法回到父窗口并关闭当前页面的逻辑不得行了。
关闭窗口的方法能够起作用,但不一定会回到父窗口了,这肯定不行。
后来找了一些资料的实现方法:
说是在页面上设置一个隐形按钮,满足条件之后触发这个按钮。我尝试过这种方法,这种方法跳转时父窗口时,相当于重新访问了一下,并不会带状态刷新,所以这种方法也是不可取的。
后续跟客户沟通后,找到了另一种方法:不使用倒计时了,使用提示信息。当满足关闭当前窗口并跳回父窗口的条件时,弹出提示信息,让用户自己操作是否返回主页。代码如下:
// 回到home页面,浏览器会拦截不是用户直接操作的跳转页面 backHome() {this.$confirm('所有数据均以保存,是否返回主页?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {// 回到父窗口home页面window.open(window.opener.location.href, window.opener.name);// 关闭当前浏览器window.close();}).catch(() => {window.open('about:blank');window.close();}); },
以上就是所有的内容了,如果有更好的方法,请多多留言!!!