自9月20日的safari 11更新以来 - 以下代码(Javascript)一次只打开1个窗口(在safari 10.1上,它会全部打开)。
是否可以在safari 11中执行此操作,如果可以,如何执行此操作?
我的代码(只是一个例子):
window.open("https://www.stackoverflow.com");
window.open("https://www.google.com");
window.open("https://www.youtube.com");
更新:
答案 0 :(得分:2)
首先,我从测试中观察到了Safari 11的行为:
window
对象的访问(不选中“阻止弹出窗口”时)。window.open
来电(在我的测试中需要> 1秒)。所以,你已经发现了解决这个问题的一种方法:添加延迟。
这是另一种允许您打开多个弹出窗口而不需要延迟的方法,使用以下知识:当“阻止弹出窗口”未选中时,每个窗口可以打开一个弹出窗口而没有延迟。在您的示例中考虑了三个弹出窗口,这是一般流程:
以下是我为处理此流程而构建的内容:
/**
* Handle the passed hrefs for Safari, which requires special/different
* handling than other browsers. Open each one in a new window (popup)
* and delegate the opening of the next popup to each new popup. Handle
* Safari's global popup blocker setting and inform the primary page
* (via postMessage) when the blocker is enabled, so a notification can
* be shown to the user.
*
* @param {Array} hrefs hrefs of popups to open
* @param {Function} safariPopupOpener Self reference. Required for
* injecting into next popup.
* @param {Window} primaryWindow Reference to the primary page
* Window object. Required for
* sending postMessage back.
* @param {string} blockedMessage Message body to send back in
* postMessage.
*/
var safariPopupOpener = function(
hrefs,
safariPopupOpener,
primaryWindow,
blockedMessage
) {
var newWindow = window.open('//url/of/the/blank/page/on/your/domain');
var popupOpenerScript = document.createElement('script');
// Must add these all to the popup's window object as the
// execution context of opener() below where they're used is the
// next popup, not the current window
newWindow.openAllResultHrefs = hrefs;
newWindow.openAllResultOpener = safariPopupOpener;
newWindow.primaryWindow = primaryWindow;
newWindow.blockedMessage = blockedMessage;
/**
* Logic to inject into the popup
*/
function opener() {
var hrefsCopy = window.openAllResultHrefs.slice();
// Delete the first item from the array for injecting into
// the next popup
hrefsCopy.shift();
if (hrefsCopy.length > 0) {
// Even when popups are blocked in Safari, one popup is
// always allowed to open. However any other popups
// opened sequentially are blocked. Also, access to the
// one popup's window object is restricted, so this
// tries to open the second popup, if window object is
// restricted (which occurs before another popup is
// opened), catches the resulting error, closes the
// first popup and sends a message back to the primary
// page that popups are blocked.
try {
window.openAllResultOpener(
hrefsCopy,
window.openAllResultOpener,
window.primaryWindow,
window.blockedMessage
);
} catch (e) {
// Optional: Send a message back to the results page that
// popups have been blocked
window.primaryWindow.postMessage(
window.blockedMessage,
window.primaryWindow.origin
);
// Close the (first) popup window (first because
// we only reach this case when popups are blocked
// and we've only successfully opened one popup)
window.close();
}
}
// Redirect to the popup href
window.location.href = window.openAllResultHrefs[0];
}
// Inject the self-executing opener function so it'll run on load in
// the opened popup
popupOpenerScript.innerHTML = '(' + opener.toString() + '());';
newWindow.addEventListener('load', function() {
// Append the script to the new window's body
this.document.body.appendChild(popupOpenerScript);
});
}
postMessage
发送回主窗口,以便它可以处理阻止(例如向用户显示消息)。因此,在主页面上需要message
侦听器。postMessage
但是当弹出窗口被阻止时我无法访问window.opener
。也可能有很大的改进空间,但我已经花了太多时间在这上面: - ))