这两天做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和安卓执行顺序会有这种出入?望告知