最近在做專案的時候碰到了使用window.open被瀏覽器攔截的情況,搞得人無比鬱悶啊,雖然在自己的環境可以對頁面進行放行,但是對用戶來說,不能要求用戶都來通過攔截。何況當出現攔截時,很多小白根本不知道發生了啥,不知道在哪裡看被攔截的頁面,簡直悲催啊~~。
另外,可以發現,當window.open為使用者觸發事件內部或載入時,不會被攔截,一旦將彈出程式碼移到ajax或一段非同步程式碼內部,馬上就出現被攔截的表現了。
原因分析&深入研究當瀏覽器偵測到非使用者操作產生的新彈出窗口,則會進行封鎖。因為瀏覽器認為這不是一個使用者希望看到的頁面。
例如對js中直接執行的,如下程式碼:
js code:
// 直接開啟一個頁面window.open('//www.baidu.com', '_blank');
瀏覽器ie8 chrome 40 firefox 34 opera 27 safari 5.1.7
是否阻止彈出NNYYY 而對於以下程式碼:
js code:
document.body.addEventListener('click', function() { window.open('//www.baidu.com', '_blank'); });
所有瀏覽器都不會攔截。
綜上所述,各瀏覽器對攔截時機的判斷不一致,而對於放在ajax回呼中的程式碼,反應又不相同了,這裡就不再贅述。但是,被瀏覽器攔截我們程式碼中要彈出的視窗並不是程式設計師所希望的。
解決方案:1.使用a標籤替代
給出如下函數,將此函數綁定到click的事件回呼中,就可以避免大部分瀏覽器對視窗彈出的攔截:
js code:
function newWin(url, id) { var a = document.createElement('a'); a.setAttribute('href', url); a.setAttribute('target', '_blank'); a.setAttribute('id ', id); // 防止重複加入if(!document.getElementById(id)) document.body.appendChild(a); a.click();}
2.使用form的submit方法開啟一個頁面
這種方法需要建構一個from,然後由js程式碼觸發form的submit,將表單提交到一個新的頁面,程式碼較長,在這裡就不寫了,大家知道有這種方案就行了。
大家注意,以上兩種方法都不適合放在ajax的回呼函數中,如果放在回呼函數中,還是會被瀏覽器攔截。
3.終極解決方案--先彈出窗口,然後重定向
第三種方案,其實是一種變通方案,核心想法是:先透過使用者點選開啟頁面,然後再對頁面進行重定向。範例程式碼如下。
js code:
xx.addEventListener('click', function () { // 開啟頁面,這裡最好使用提示頁面var newWin = window.open('loading page'); ajax().done(function() { // 重導向到目標頁面newWin.location.href = 'target url'; }); });
以上方法其實是打開了兩個地址,所以建議大家打開第一個地址的時候給出一個類似'當前頁面正在加載中,請稍後。 。 '的簡單提示頁,這樣可以避免打開兩次真正的目標頁面,讓使用者察覺到頁面的重定向。
解決方法二:
<a href=javascript:; onclick=dialog();>點擊彈跳窗</a><script>function dialog(){ $.ajax({ url: 'url', type: 'POST', dataType: 'json ', async: false, // 這裡必須定義為同步data: {param1: 'value1'}, success: function(data){ window.open(data.url, '_blank'); //發起彈跳窗} })} </script>
該方法弊端:
實測能解決大部分瀏覽器的攔截問題,但是解決不了安全軟體的攔截(360不會攔截,但是QQ管家會攔截)
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。