Javascript 确认对话框在iOS10上失去焦点

Javascript 确认对话框在iOS10上失去焦点,javascript,browser,mobile-safari,confirm-dialog,safari10,Javascript,Browser,Mobile Safari,Confirm Dialog,Safari10,在我的网站的移动版本中,我有一个JavaScript确认对话框,在特定情况下出现。使用setTimeoutI触发确认对话框。 无论用户在哪个选项卡中,他都会看到确认对话框,但在iOS 10中会失去焦点 在iOS版本8和9中,当我有两个选项卡并且我在第二个选项卡中时,确认对话框会像它应该的那样出现在前面 有什么解决办法或解决办法吗 var cf = confirm("Close?"); if (cf){ do that....} else { do this... } SafariDriver

在我的网站的移动版本中,我有一个JavaScript确认对话框,在特定情况下出现。使用
setTimeout
I触发确认对话框。 无论用户在哪个选项卡中,他都会看到
确认对话框
,但在iOS 10中会失去焦点

在iOS版本8和9中,当我有两个选项卡并且我在第二个选项卡中时,确认对话框会像它应该的那样出现在前面

有什么解决办法或解决办法吗

var cf = confirm("Close?"); 
if (cf){ do that....} else { do this... }

SafariDriver是在JS中实现的,因此为了拦截对
警报
确认
提示
的调用,必须覆盖网页上下文中的函数

将注入的脚本更改为作为
开始
脚本而不是
结束
脚本注入-这意味着在加载DOM之后,但在解析之前注入脚本(而不是在onload事件之后注入):

重写测试页面上下文中的全局警报函数,而不是注入的脚本。这与executeScript命令的要求类似。因此,我们注入的脚本应该做的第一件事是向DOM添加一个脚本标记,用于设置警报覆盖。应将此脚本标记添加为documentElement的第一个子元素,以确保它在页面中的任何其他子元素之前执行。这将确保我们在页面中的任何内容有机会触发警报之前设置警报处理程序

一旦触发警报,我们必须通知扩展有警报,同时阻止页面中当前的JS线程。通常,我们的页面脚本使用window.postMessage与注入的脚本通信。postMessage异步触发MessageEvent。为了保持同步性,我们可以手动触发MessageEvent:

使用MessageEvent而不是其他一些DOM事件,这样我们就可以包含一个描述警报的JSON对象。

var event = document.createEvent('MessageEvent');
event.initMessageEvent('message', false, false, {
  type: "alert",  // confirm, or prompt
  text: "hello"
}, window.location.origin, '0', window, null);
window.dispatchEvent(event);
注入的脚本必须侦听对页面警报消息的响应。为了将警报同步发送到扩展进行处理,我们可以(ab)使用Safari扩展的机制阻止加载内容:

注意,扩展的警报响应必须使用另一条消息传回页面,因为我们正在跨越上下文边界。唯一的其他选项是将响应存储在DOM上,以便在另一侧读取

最后一步,这是一个开放式问题,是扩展应该如何处理警报。由于我们维护警报的阻塞行为,因此不可能再让命令执行(即使它们导致未处理的警报错误)

一种可能性是让WebDriver客户端参与警报处理。除了提供WebSocket服务器外,WebDriver客户端还将提供一个XHR端点。当检测到警报时,服务器将向该端点发送同步POST XHR。客户端应仅在用户接受或解除警报(或从另一个命令引发未处理的警报错误)后响应。当接收到XHR响应时,扩展完成链并将响应发送回注入的脚本

你可以找到更多

window.addEventListener('message', function(e) {
  // Create a beforeload event, which is required by the canLoad method
  var e = document.createEvent('Events');
  e.initEvent('beforeload', false, false);

  // canLoad sends and waits for a response synchronously. It is the only
  // synchronous function in the Safari extension messaging API.
  var response = safari.self.tab.canLoad(e, e.data);

  // Send the response back to the page using another MessageEvent.
  var responseEvent = document.createEvent('MessageEvent');
  responseEvent.initMessageEvent('message', false, false, {
    accepted: response.accepted,
    response: response.value
  }, window.location.origin, '0', window, null);
  window.dispatchEvent(responseEvent);
}, true);