这两天做H5页面,使用swiper+iscroll+fastClick,并没有用swiper提供的tap和click事件,自己在元素上bind,因为回调函数是统一处理,就没用swiper,后面发现即使是使用了swiper提供的,也是会有问题,本人用的ios设备,做完一切流畅,但是提交给测试确发现安卓有个问题,如题。

swiper v4.5.0

研究了一下swiper源码,发现初始化的时候会给容器注册一个click事件

这里是用来判断用户当前是否触发touchmove事件,如果是touchmove那么就阻止所有bind元素的click事件,这个逻辑没错啊,于是继续在模拟器中调试。

打了各种断点调试,发现swiper绑定的touchend中代码逻辑执行顺序在两个客户端中是不一样的,神奇。

如上图,ios中先执行了onClick方法,后执行Utils.nextTick的回调;android则相反,先执行nextTick的回调;然后看了下,swiper是怎么封装的回调Utils.nextTick

??? 好像没问题啊,eventLoop执行顺序对的啊。难道是安卓上setTimeout和event执行顺序异于其他浏览器。

敲段代码测试一下(注意,下面这段代码直接用浏览器打开,执行顺序是相同的,但是,找个容器去挂载,比如tomcat,执行顺序的问题就出来了):

<!DOCTYPE html><html><head>  <title>touchend-click-setTimeout</title>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  <meta name="viewport"    content="initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no,target-densitydpi = medium-dpi">  <meta name="format-detection" content="telephone=no">  <meta name="apple-touch-fullscreen" content="YES">  <meta name="apple-mobile-web-app-capable" content="yes">  <meta name="apple-mobile-web-app-status-bar-style" content="black">  <link rel="stylesheet" type="text/css" href="./lib/swiper.css" />  <link rel="stylesheet" type="text/css" href="./lib/pullToRefresh.css" />  <style>    body,html{      padding: 0;      margin: 0;      border: 0;    }    .btn{      height: 50px;      line-height: 50px;      text-align: center;      background: #ccc;      color: #fff;      width: 200px;      margin: 0 auto;    }  </style></head><body>  <section id="wrapper">    <ul style="background:#F3F4F6;">      <div class="btn">touchend-btn</div>    </ul>  </section></body><script type="text/javascript" src="./lib/jquery.min.js"></script><!-- <script type="text/javascript" src="./lib/fastclick.js"></script><script type="text/javascript" src="./lib/iscroll.js"></script><script type="text/javascript"  src="./lib/pullToRefresh.js"></script><script type="text/javascript" src="./lib/swiper.js"></script><script type="text/javascript" src="./lib/vconsole.min.js"></script> --><script>  // 原生默认的执行顺序:  // ios执行顺序: touchstart -> touchend -> click -> setTimeout  // android执行顺序: touchstart -> touchend -> setTimeout -> click  // FastClick.attach(document.body);  // refresher.init({  //   id: "wrapper",  //   pullDownAction: function () {  //   },  //   pullUpAction: function () { }  // });  $('.btn').on('touchstart',function(){    console.log('touchstart');  });  $('.btn').on('touchmove',function(){    console.log('touchmove');  });  $('.btn').on('touchend',function(){    console.log('touchend');    setTimeout(function(){      console.log('touchend:setTimeout');    },0);  });  $('.btn').on('click',function(){    console.log('click');  });</script></html>

结果如下
ios执行顺序: touchstart -> touchend -> click -> setTimeout
android执行顺序: touchstart -> touchend -> setTimeout -> click

到这里我就没继续往下找原因了,直接修改,解决问题。

不知道有没有大佬能帮忙看下,为啥ios和安卓执行顺序会有这种出入?望告知