为了账号安全,请及时绑定邮箱和手机立即绑定

有关于新页面弹窗的问题

有关于新页面弹窗的问题

xue5hen 2018-07-20 13:38:34
1、需求        网站内有一个table做的客户列表,其中一列有个“查看详情”的按钮,点击后会向服务器发起一个请求(参数为该行客户的id信息),然后根据返回值判断是否打开一个新页面(返回true则打开新页;返回为false则toast提示“无法查看!”)。        这个需求其实蛮常见,实现似乎也很简单,但还是遇到一些值得一提的情况。2、方案1)方案一:window.openqueryUserViewAuth(params).then((res) => {     If (res.data.isSuccess) {         Window.open('/newPage')     } else {...} })        但是当点击按钮触发弹窗时,被浏览器拦截了,项目负责人认为这个体验是不好的,所以需要考虑如何解决这个问题。        在此之前,先提一下浏览器拦截弹窗的原因,网上搜了下,说是因为“ajax回调中的上下文已不是用户行为了,从安全角度出发,浏览器进行了拦截”,这意味着“在函数内部新建a标签再去触发a标签的click事件”也是不可行的。2)方案二:控制a标签的href跳转        于是有提议说是否可以“直接使用a标签替代table中的按钮,然后当用户点击时根据ajax的返回结果去‘阻止/放行’a标签的href行为”。这个想法听起来不太能做到,实际也确实没成功,不过测试中有点儿小发现,虽然目测没什么实用价值,但还是忍不住提一嘴:        ① 首先,如果要阻止a标签的href跳转,常见的伎俩如下;<a href="newPage.html" onclick="return false;">测试</a>        ② 但这显然不满足此次的需求,得让返回值是可控的,所以尝试变形;<a href="newPage.html" onmousedown="this.x=fn();" onclick="return this.x;">测试</a> <script>     function fn() {return false} </script>        ③ 上述②的变形是可以的,但那代码都是同步的,所以→再变;<a href="newPage.html" onmousedown="this.x=fn();" onclick="return this.x;">测试</a> <script>     function fn() {         setTimeout(function(){return false},0)     } </script>       OK,到这里KO了,见证奇迹的时刻并未降临。3)方案三:        苦思无望,只好再到搜索引擎上找找思路,(其实就是解释弹窗为什么被拦截的那帖子),提到了一个思路“在click事件中先打开一个空白的新窗口,然后再进行ajax请求,请求后再去更改新窗口的url”。这方法不错,但可惜并不适用于此次的项目需求,毕竟如果请求发现res.data.isSuccess为false(即不应该打开新页面),“这时再用close去关”并不是一个好的用户体验,何况如果请求返回过慢,那个新窗口会以空白之身杵在那里很久,也不好。4)结束        后来,项目负责人提出暂通过后端来解决,方案如下:前端直接用a标签做按钮,在href上拼接上get请求的地址(即上述的ajax请求),当用户点击时触发请求,然后再由后端做302重定向。3、求助        各位如果有什么好对策,希望能点拨一下。
查看完整描述

1 回答

已采纳
?
慕勒0069038

TA贡献143条经验 获得超39个赞

很抱歉这几天都没有回复, 赶项目= = ,今天抽空看了一眼,给你写了一个 你试试

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="jquery/js/jquery.min.js"></script>
  <script>
     $(document).ready(function (e) {

        $('span').bind('click',function(e,canjump){
           console.log(1);
          if(!canjump){
             e.preventDefault();
             $('span').trigger("myclick");
             }
        });
        $('span').bind('myclick',function(e){
           async function a() {
              try{
                 return await new Promise((resolve, reject) => {
                    setTimeout(function () {
                       resolve(true);
                    }, 1000);
                 });
              }catch (e){
                 return await Promise.reject(false);
              }
           }
           a().then(function (canjump) {
              console.log(13);
              $('span').trigger("click",[true]);
           }).catch(function (err) {
              console.log(err);
           })
        });
     });
  </script>
</head>
<body>
  <a href="test1.html" ><span>测试</span></a>
</body>
</html>


查看完整回答
1 反对 回复 2018-07-24
?
慕勒0069038

TA贡献143条经验 获得超39个赞

方案2  的 可以参考下 es6(es7) 的 async、await 

 方案2 你的不成功的原因是 应该是fn() 内部的setTimeout 相当于异步方法, 调用fn的时候 没有return false 出来,

其实有个方法, 就是 成功后弹个确认框(layer就行) ,里面说 即将前往新的页面 ,给一个确定和取消, 确定就window.open(), 这样不就不会被拦截了么

查看完整回答
反对 回复 2018-07-20
  • xue5hen
    xue5hen
    谢谢,我之后再去查查async|await的用法,之前实际也试过,但我对这玩意儿一直用不好,当时测试没成功就撇一边了,因为怕是自己用的有问题就没提。 至于您提到的后一种方法,网上那个文章里也提到了,因为会多一步用户确认,所以没考虑它。
  • xue5hen
    xue5hen
    我刚又试了试async|await,不知道用法是否正确,现在还达不到目的,麻烦再帮着看下,给改改 http://jsrun.net/69gKp/edit
  • 1 回答
  • 0 关注
  • 1060 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信