Since the safari 11 update on September 20 - the following code (Javascript) only opens 1 window at a time (on safari 10.1 it opens them all).
Is it possible to do this in safari 11 and if yes, how?
My code (just an example):
window.open("https://www.stackoverflow.com");
window.open("https://www.google.com");
window.open("https://www.youtube.com");
Update :
Update: This question and solution is still valid as of Safari 13.
First, here's the behaviour of Safari 11 I've observed from testing:
window
object is restricted (not the case when "Block pop-up windows" is unchecked).window.open
calls must be delayed (>1s required in my testing).So, you've discovered one way to get around this: Add a delay.
Here's one more way that will allow you to open multiple popups without the need for a delay, using the knowledge that when "Block pop-up windows" is unchecked, each window may open one pop-up without a delay. With the three popups in your example in mind, here's the general flow:
The following is what I've built to handle this flow:
/**
* 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
back to the primary window so it can handle the blocking (e.g. display a message to the user). So, would require a message
listener on the primary page.postMessage
may not be necessary but I couldn't access window.opener
when popups were blocked. Also probably lots of room for improvement, but I've already spent too much time on this :-))If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With