首先,這裏是我的測試中觀察到野生動物園11的行爲:
- 一個彈出窗口總是允許打開(即使在全球性的「阻止彈出窗口」設置被選中)。當選中「阻止彈出窗口」時,訪問彈出窗口的
window
對象將受到限制(而不是在「阻止彈出窗口」未選中時)。
- 正如您所描述的,當「阻止彈出式窗口」未選中時,多個
window.open
調用必須延遲(在我的測試中需要> 1秒)。
- 當「Block pop-up windows」被選中時,似乎只有一個彈出窗口被允許打開(儘管使用了延遲)。
所以,你已經發現了一種解決這個問題的方法:添加延遲。
還有一種方法可以讓您在不需要延遲的情況下打開多個彈出窗口,使用「取消選中」阻止彈出窗口「的知識時,每個窗口可以毫不拖延地打開一個彈出窗口。以您的示例中的三個彈出窗口爲例,以下是一般流程:
- 在您的域上打開一個彈出窗口(空白頁)。
- 通過注入一個在加載時執行它的腳本來委託下一個彈出窗口的打開。
- 將第一個彈出窗口重定向到所需的URL。
- 重複,直到所有彈出窗口都打開。
以下是我已經建立了處理這個流程:
/**
* 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
。也可能有很大的改進空間,但我已經花費了太多的時間在這:-)
可能是因爲safari默認設置不啓用新窗口彈出。您必須將瀏覽器配置爲接受彈出窗口。 – 2017-09-23 16:21:20