javascript - setTimeout 如何处理 JavaScript/TypeScript 中的窗口来源和上下文?(使用 window.close() 函数关闭选项卡)
问题描述
我最近参与了一个使用 React 创建一个简单站点的项目。调用另一个域上的 Iframe 让用户拍摄一些照片并将它们发送到数据库,然后关闭 Iframe。在移动设备上,由于各种限制(如在 iOS 上),为拍摄照片打开了一个新选项卡,而不是 iframe。拍摄照片后,通过 iframe 和新选项卡上的后退按钮返回原始站点。
我必须让后退按钮在新打开的选项卡上工作。拍摄照片意味着遵循一些步骤,这些步骤在新标签的窗口中创建了历史记录。我尝试了很多方法,使用 BroadcastChannel、postMessage 和 localStorage,尝试与原始站点(我说的是在另一个域上)通信,告诉它关闭窗口,但没有成功。在选项卡的窗口中有历史记录意味着window.close()
从选项卡调用的函数仅在第一步中起作用,即在打开新选项卡后立即起作用。
在尝试了几个星期没有成功后,我请了一位资深的 JS 程序员来帮忙。
他的有效解决方案让我感到困惑:
在返回按钮的单击事件调用的函数中,他放置了以下代码:
function backOnClick() {
//some code
if (onMobile) {
setTimeout(() => window.close(), 200)
return
}
//some more code
}
为什么这行得通,但window.close()
直接调用(不带 setTimeout 函数)却不行?
它是否必须与上下文有关,或者 setTimeout 执行的线程是否没有与之关联的历史记录?我理解为什么其他解决方案失败了,但我真的很想知道为什么会这样。
我希望他的解决方案可以帮助那些希望在网络浏览器中关闭标签并遇到问题的人。向高级开发人员致敬。每次看到他们解决问题时,我都会感到敬畏。干杯!
编辑:
js
在与其他一些程序员讨论此事后,我想我明白会发生什么。该函数backOnClick()
在服务器端执行,服务器无法关闭客户端的窗口。通过将close
语句放入setTimeout()
函数中,服务器将关闭作业交给客户端,客户端可以关闭自己的窗口。
希望这可以帮助某人更好地了解幕后的机制。
解决方案
推荐阅读
- inheritance - 使用嵌入式接口字段在 Go 中正确实现继承
- powershell - 使用powershell对CSV文件中的列进行排序
- c# - 从 WPF 控件中删除名称
- ios - 将数据(标签)从 TableViewCell 传递到另一个 ViewController
- jquery - 使用居中的元素保持相同的动画
- elixir - 如何规范化 Elixir 中的数字列表?
- android - Moxy 的 MVP。未调用 Fragment 中 Presenter 的回调方法(getViewState() 不为空)
- javascript - 在 node.js 中使用 es6 类有用吗?
- batch-file - Ffmpeg - 感叹号停止水印
- google-play - 如果我停止在 Google Play 上从某个国家/地区发布我的应用会怎样?