問題描述:javascript
當使用window.open打開窗口時,若是用戶瀏覽器設置了攔截彈出窗口(以下圖的chrome),咱們的窗口則會被瀏覽器攔截。php
注: 當window.open爲用戶觸發事件內部或者加載時,不會被攔截,一旦將彈出代碼移動到ajax或者一段異步代碼內部,立刻就出現被攔截的表現了。html
緣由分析:java
當設置了瀏覽器攔截時,若是瀏覽器檢測到非用戶操做產生的新彈窗,就會對其進行攔截。web
好比在js中直接執行以下代碼:ajax
window.open('http://www.baidu.com','_blank');
瀏覽器 | IE8 | chrome40 | firefox34 | opera27 | safari5.1.7 |
---|---|---|---|---|---|
是否阻止彈出 | N | N | Y | Y | Y |
而下列代碼:chrome
document.body.addEventListener('click',function(){ window.open('http://www.baidu.com','_blank'); })
全部瀏覽器都不會攔截。json
綜上所述,各瀏覽器對攔截時機的判斷不一致,而對於放在ajax回調中的代碼,反應又不相同了,這裏就再也不贅述。瀏覽器
解決方案:app
newWin(url,id);
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(); }
這種方法須要構造一個from,而後由js代碼觸發form的submit,將表單提交到一個新的頁面 。
注:比較麻煩。
注:以上兩種方法不適合放在ajax的回調函數中,若是放在回調函數中,依然會被瀏覽器攔截 。
var this_id = document.getElementById('open_company_'+id); this_id.addEventListener('click',function(){ var newWin = window.open(web_url);//過渡頁面的url $.ajax().done(function(){ newWin.location.href = url;//實際打開頁面的url }) });
以上方法實際上是打開了兩個地址,過渡頁面和實際展現頁面,因此建議你們打開第一個地址的時候給出一個相似‘當前頁面正在加載中,請稍後。。’的簡單提示頁,這樣能夠避免打開兩次真正的目標頁面,讓用戶察覺到頁面的重定向。
我係統中實現的功能:
列表中展現公司基本信息,點擊某一行,請求後臺數據,判斷該條數據的使用權限有沒有過時:1.過時:則跳轉至收費頁面;2.未過時:則跳轉至公司詳細數據頁面。
通過實際檢測,若是第三種的代碼所有加到ajax的回調函數中,彈窗依然不能彈出:
錯誤代碼:
function is_gq(id){ var this_id = document.getElementById('open_company_'+id); $.post('<?php echo Configure::read('webpath') ?>BasicSearches/is_gq', {gs_id: id}, function(data, textStatus, xhr) { var newWin = window.open(web_url+'ShPage/loading_page');//加載過渡頁面 if(data ==0){//已過時 $.messager.alert('已過時!','對不起,該條數據已過時,請從新購買'); var url = web_url+'BasicSearches/pay_company?gs_id='+id; this_id.addEventListener('click',MyNewWin(url,newWin)); return false; }else{ var url = web_url+'ShPage/index?fid='+id; this_id.addEventListener('click',MyNewWin(url,newWin)); } }); }
說明:由於加載過渡頁面的代碼放到了回調函數中,此頁面依然不能打開,因此出錯。
正確代碼:
function is_gq(id){ var newWin = window.open(web_url+'ShPage/loading_page');//加載過渡頁面,這句話必定要放到回調函數外才能正確執行 var this_id = document.getElementById('open_company_'+id); $.post('<?php echo Configure::read('webpath') ?>BasicSearches/is_gq', {gs_id: id}, function(data, textStatus, xhr) { //已過時 if(data ==0){ $.messager.alert('已過時!','對不起,該條數據已過時,請從新購買'); var url = web_url+'BasicSearches/pay_company?gs_id='+id; this_id.addEventListener('click',MyNewWin(url,newWin)); return false; }else{ var url = web_url+'ShPage/index?fid='+id; this_id.addEventListener('click',MyNewWin(url,newWin)); } }); } function MyNewWin(url,newWin){ $.ajax().done(function(){ newWin.location.href = url; }) }
說明:加載過渡頁面的代碼要放到回調函數外才能保證彈窗首先打開 ,而後才能重定向。
var preview_btn = $('.app_item[title = "預覽"]'); preview_btn.on('click',function () { var newWin = window.open('about:blank');///////////////// $.ajax({ type: 'post', url: '/app/saveSession', data: {jsonStr: sendData}, success: function (result) { if (result.success) { var url = '/app/preview/' + settings.appId; newWin.location.href = url;/////////////////////// } else { alert("預覽失敗"); } }, error: function () { alert("請求失敗"); } }); })
參考文章:http://www.mamicode.com/info-detail-495157.html