大家在做项目的时候,肯定会和我一样,碰到各种各样的问题,然后熟练的打开搜索引擎,输入些关键字,开始解决问题。最近在做一个效果,中间就碰到了各种问题,接下来我把解决这个问题的过程发出来分享下,也算是我的一个小心得。
要做的效果其实很简单,就是在做支付的时候,出现一个弹出层,然后跳到一张新页面,类似于下面两张图片的效果:
页面一 | 页面二 |
这里面就是两个技术点,一个是弹出层的实现,另外一个就是通过脚本弹出一个新页面。出现弹出层这个很好解决,我使用了一个方便的插件artDialog。第二个问题弹出一个新页面,花了点时间,后面用的实现技术是非常简单的,但中间就是发生了很多波折。心情也像过山车一样跌宕起伏.......
这个效果,我本来实现的方式是发送一个ajax请求,然后返回请求,最后在回调函数中跳转新页面和弹出提示层。
一、使用location.href实现
这是我最先想到的,然后自己YY了一下,给location加了个target属性,以为这样就能弹出新页面了,实在太无知啦,毫无效果,还是在当前页面跳转。这里就暴露了我解决新问题,总是喜欢从自己用过的技术着手,总是想把那些技术嫁接过来,拼上去,有点碰运气的感觉。发现失败了,就立刻打开搜索引擎,输入最直接的关键字。
二、搜索JS弹出新窗口
输入这个最直接的关键字,搜索引擎也没让我失望,一下子出现了好多的相关资料,我一般比较喜欢打开个人博客,个人博客的排版很整齐,像那个脚本之家的排版实在是乱。
有多个解决方案,我选了一个大家说的最多的方法,使用window.open(),这个的确很简单,只要把url地址作为参数放进去后就行,但是用了浏览器会阻止这个页面弹出,如下图:
这个东西如果给用户看的话,一定会引起恐慌啦,一般只有弹出垃圾页面或广告等信息的时候会出现,用户肯定会习惯性的认为你这里有蹊跷。接下来我就根据window.open来搜索了,想从这里找到个突破口。
三、搜索js window.open 不拦截
方法一:先弹出一个空页面,然后再用location.href,实践证明不可行。
var d=window.open(); d.location = 'http://www.cnblogs.com/strick';
方法二:利用浏览器的冒泡事件,这个方法高大上,但是我水平太菜了,不会用,后面还查到了一个差不多的方法,里面稍微有点修改,本来以为那个方法可以解除我的烦恼,但最终还是失败了,在执行到window.open的时候还是出现了阻止
clickOpenWin: function(f){ var dataKey = "clickOpenWin.dataKey" var me = $(this); var A = me.data(dataKey); var returnData = null; if(!A){ A = $(""); me.data(dataKey, A); A.click(function(e){ if(returnData){ A.attr("href", returnData); }else { A.before(me); e.stop(); } }); } me.mouseover(function(){$(this).before(A).appendTo(A);}); me.mouseout(function(){A.before($(this));}); me.click(function(){ A.attr("href", "#|"); returnData = f.apply(this, arguments); });
经过这一连串的失败,我就想到一个问题,为什么页面上面用鼠标点击弹出新页面不会阻止,而用脚本弹出就会被限制呢?
四、搜索js模拟鼠标点击
想到动态添加一个a标签,用a标签来模拟打开新页面,柳暗花明又一村的感觉,而且实现方式也很简单
var openLink = $("a"); openLink.attr('href', 'http://www.cnblogs.com/strick/'); openLink.attr('target', '_blank'); openLink[0].click();
但是还是出现了很不受欢迎的拦截提示,作死的节奏。
继续搜索,发现有人用纯JS的语法来写,这个时候马上就怀疑自己是不是因为用了jQuery与动态生成的原因,有时候就是会因为一个小细节导致错误的,我马上就急冲冲的修改代码,在页面中加上a标签,然后用脚本click一下,依然是那个问题,唉
<a target="_blank" href="http://www.cnblogs.com/strick" id="myLink"></a> <script language="text/javascript"> function AutoClick() { var myLink = document.getElementById("myLink"); myLink.click(); } </script>
五、想利用弹出层来做跳转
这个我后面想了下,的确能做到在弹出层里面跳转,但是平时看到的那些效果完全感觉不出来是用弹出层的,更不会是用iframe来做的效果,否决了这个方案
六、搜索jquery 广告强制弹出窗口
平时浏览网站的时候,有些流氓页面还是会被弹出来,莫非有什么强力方法可以做到吗?
顺着这个思路去搜索,查到了一个相关代码,如下:
function windowOpen(){ var a = document.createElement("a"); a.setAttribute("href", url); if(target == null){ target = ''; } a.setAttribute("target", target); document.body.appendChild(a); if(a.click){ a.click(); }else{ try{ var evt = document.createEvent('Event'); a.initEvent('click', true, true); a.dispatchEvent(evt); }catch(e){ window.open(url); } } document.body.removeChild(a); }
从外形看,这个代码挺高大上的,看了下后,发现其实还是在用模拟a标签以及window.open的方法,一下子就感觉希望不大,还是抱着试试的态度操作了下,果不出所料
中图还看到一个用form方法弹出的方式:
<form id="form" action="http://www.cnblogs.com/strick" method="get" target="_blank"> </form> <script language="text/javascript"> function AutoClick() { document.getElementById("EmailForm").submit(); } </script>
这个方法倒挺像那么一回事的,有感觉,有预感能行,然后马上实验下,额,还是万恶的弹出层。
一直折腾到了吃晚饭的时候,吃饭的时候就在想,其他网站到底是什么高级的方法来实现的呢!!!突然想到可以去扣一下有这个效果的网站脚本,看看是怎么实现的。我这种扣脚本的事经常干,而且非常有效,经常会有很多意外收获,这次也不例外。
七、从实现这个效果的网站上扣脚本代码
用firebug查看html代码,然后一个一个查看脚本,网站的脚本没有压缩,非常幸运,后面找到了相关方法。非常意外,不是啥高级的方法,其实就是用form表单提交,target="_blank",尼玛,这不是和我刚刚的代码一样呀,为嘛他能顺利弹出,但是我这里死活就是拦截,本来以为是网站做了什么设置,YY了一下,想不到有啥设置,然后看了下html与js代码,终于发现了不同。
原因就是我打开新窗口的代码是放在ajax的回调函数中,而那个网站的代码没有写在回调函数中。找到了问题根源,就能迎刃而解啦,终于出现了我想要的效果
$('#open_new').submit(); dialog.showPayLayer(); // var fn = function(json) { // if(_model.isSuccess(json)) { // dialog.showPayLayer(); //location.href = json.data.url; // } // viewUtil.setError(json.msg); // }; //_model.post($(e.target), {cash:cash, ctype:ctype, type:'cashin'}, fn);
页面效果与那些后台代码不同,js、css、html等都暴露在外面,随时能够查看,想做效果,而且看到了网上的实践,完全可以查看相关代码,然后根据这些代码整合一下,省时省力,做前端得有点copy的能力。在解决这个问题的时候,我也是一点一点的分析,虽然过程很波折,但是在排查的过程中还是有很多体会,网上看到的解决方法不一定试用你的代码,根据这些方法从各个角度分析,总归会找到些线索,解决你现在的问题。
这个demo是需要放到php的apache下面的htdocs执行文件中,才能看到相关效果,不然会出现拦截的,直接解压,将pop文件夹放到htdocs中就可以了,如果改动文件夹的名字就需要在config.js的配置文件中修改domain
demo下载: