问题描述: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