Javascript 在safari 11中打开多个弹出窗口
自9月20日safari 11更新以来,以下代码(Javascript)一次只打开一个窗口(在safari 10.1上,它会打开所有窗口) 在safari 11中有可能做到这一点吗?如果有,如何做到 我的代码(只是一个示例): 更新:Javascript 在safari 11中打开多个弹出窗口,javascript,safari,Javascript,Safari,自9月20日safari 11更新以来,以下代码(Javascript)一次只打开一个窗口(在safari 10.1上,它会打开所有窗口) 在safari 11中有可能做到这一点吗?如果有,如何做到 我的代码(只是一个示例): 更新: 浏览器首选项设置为启用弹出窗口且不阻止任何内容 如果我在每个打开的窗口之间设置一个至少0.5秒的“setTimeout()”,代码就可以工作了——这可能是因为safari的新更新不想让我用太多的弹出窗口“垃圾邮件”用户 更新:此问题和解决方案自Safari 13起
更新:此问题和解决方案自Safari 13起仍然有效。 首先,以下是我在测试中观察到的Safari 11的行为:
- 始终允许打开一个弹出窗口(即使选中了全局“阻止弹出窗口”设置)。选中“阻止弹出窗口”时,对弹出窗口的
对象的访问将受到限制(未选中“阻止弹出窗口”时不是这种情况)窗口
- 正如您所描述的,当取消选中“阻止弹出窗口”时,必须延迟多个
调用(在我的测试中需要>1s)window.open
- 当选中“阻止弹出窗口”时,似乎只允许打开一个弹出窗口(尽管使用了延迟)
/**
* 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 primary 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
消息
侦听器
可能不是必需的,但当弹出窗口被阻止时,我无法访问postMessage
。可能还有很多改进的空间,但我已经在这方面花费了太多时间:-)窗口。opener
/**
* 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 primary 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);
});
}