2017-09-23 34 views
2

9月20日にSafari 11がアップデートされて以来、次のコード(Javascript)は一度に1つのウィンドウしか開きません(Safari 10.1ではすべて開きます)。Safariで複数のポップアップウィンドウを開く11

サファリ11でこれを行うことは可能ですか?はいの場合はどうすればよいですか?

私のコード(単なる例):

window.open("https://www.stackoverflow.com"); 
window.open("https://www.google.com"); 
window.open("https://www.youtube.com"); 

更新:

  1. 好みがポップ・アップを可能にするために、何をブロックしないように設定されているブラウザ。
  2. 少なくとも0.5秒間開いたウィンドウ間に「setTimeout()」を設定するとコードが機能します。これは、サファリの新しいアップデートで、あまりにも多くのpopアップウィンドウ。
+0

サファリのデフォルト設定では新しいウィンドウポップアップが有効になっていない可能性があります。ポップアップを受け入れるようにブラウザを設定する必要があります。 –

答えて

1

まず、ここで私がテストから観察してきたサファリ11の動作です:

  • 一つのポップアップが常に(グローバル「ポップアップのブロック」の設定がチェックされている場合でも)開くことが許可されています。 「ポップアップウィンドウをブロックする」チェックボックスをオンにすると、ポップアップのwindowオブジェクトへのアクセスが制限されます(「ポップアップウィンドウをブロックする」チェックボックスがオフの場合ではありません)。
  • 説明したように、「ブロックするポップアップウィンドウ」がチェックされていない場合、window.openコールは複数回延期する必要があります(テストでは1秒以上が必要です)。
  • 「ブロックポップアップウィンドウ」がチェックされていると、(遅延が使用されても)1つのポップアップしか開くことができないようです。

これを回避する方法の1つを発見しました。遅延を追加する。

「ポップアップウィンドウをブロックする」がチェックされていないと、各ウィンドウが遅延なく1つのポップアップを開くことができるという知識を利用して、複数のポップアップを遅延なく開くことができます。例の3つのポップアップを念頭に置いて、ここには一般的な流れがあります:

  1. ドメイン上にポップアップ(空白ページ)を開きます。
  2. 次のポップアップの読み込みを、このポップアップにロードするスクリプトを挿入することによって委任します。
  3. 最初のポップアップを目的のURLにリダイレクトします。
  4. すべてのポップアップが開くまで繰り返します。私はまた、ブロッキングを検出し、それを扱うことができるので、主ウィンドウに戻りpostMessageを送ってい

    /** 
    * 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); 
        }); 
    } 
    
    • 注:

次は、私はこのフローを処理するために構築されてきたものですブロックする(例えば、ユーザにメッセージを表示する)。したがって、プライマリページにはリスナーmessageが必要です。

  • postMessageは、ポップアップがブロックされたときにwindow.openerにアクセスできませんでした。また、改善の余地はたくさんあるかもしれませんが、私はすでにこれに多くの時間を費やしています:-))
  • +0

    こんにちはマット、あなたの答えをありがとう! 私はあなたのコードを使用しませんでした(ほとんど私が理解することが難しいため)が、私はそれの背後にあるアイデア(次のポップアップを開く各ウィンドウの)を理解した - それは働いた! これを行うには少しの作業ですが、少なくともそれは動作します:) ありがとうございました。 –

    +0

    心配はいりません。タイムアウトは、私のユースケースには十分使えませんでしたので、少し必要になりました。それはまだ私の脳を傷つける! –

    関連する問題