array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 移动端页面 滚动结束 判断 - 爱码网

在做移动端的需求有时候需要用到对滚动结束进行事件绑定以完成一定的功能,先来了解一下现状。

 

在移动端,正常的一次swipe动作会依照以下顺序触发事件:

touchstart -> touchmove -> touchend ->scroll

一、IPAD

通过以下代码进行测试:

     var timestart =0;
        var timer = null;
        function log(){
            console.log("---------settimeout" + (new Date()-timestart) );
        }
        $(window).on('scroll',function(){
            console.log('-----scrollend:' + (new Date() - timestart) +'ms');
            timestart = new Date();
        });
        $(window).on('touchstart',function(){
            console.log('touchstart');
        });
        $(window).on('touchmove',function(){
            console.log('touchmove');
        });
        $(window).on('touchend',function(){
            timestart = new Date();
            console.log('touchend');
            timer =  setTimeout(log,1);
        })  

当“tap”时,依次产生如下事件:

touchstart -> touchend

当"swipe"时,依次产生如下事件:

touchstart -> touchmove * 多次 -> touchend -> scroll

在ipad中,touchend事件在手指离开时触发,由于是swipe动作,所以在手指离开后,屏幕还会滚动一段时间,直至最后停止,在最后的停止事件会触发scroll事件。

可见,在ipad中,滚动结束的判断只需要监听scroll事件即可。

那么从touchend到scroll这段时间如何操作dom呢?使用以下测试代码,一次swipe从touchend到scroll的时间大概经过0-2000ms不等(也许可能更长,依据加速度)。现在向touchend中添加setTimeout事件,设定延迟时间为1ms(几乎一定在scroll之前)。实验了四次,得到结果如下(使用weinre远程调试)

移动端页面 滚动结束 判断

可以从结果中看到,在ipad中,settimeout并没有如预想的在scrollend之前触发,反而在scrollend触发后才触发。

由这种情况可以推测,事件队列中的顺序为 touchend回调 -> scroll回调 -> settimeout函数。

所以,如果想操作touchend到scroll这段时间的动作,在ipad下是不可实现的

 

二、Android

依旧使用上述测试代码。

当“tap”时,依次产生如下事件:

touchstart -> touchend

当"swipe"时,依次产生如下事件:

touchstart -> touchmove  -> scroll*多次

另外需要注意的是,在android下,swipe虽然不会触发touchend事件,但是会在scroll事件之前触发一次touchcancel事件,即:

touchstart -> touchmove -> touchcancel->scroll*多次

在swipe过程中,并没有触发touchend事件,同时却触发了多次scroll事件,并在第一次触发scroll事件时有大概1000ms的延时。即使手指在屏幕上来回滑动,也只触发一次touchmove事件,后续过程均为scroll事件。

 

所以,如果需要做兼容性良好的滚动结束的判断,是不能根据touchend事件的触发做判断的,同时,由于scroll事件在Android中会触发多次,而在苹果中只触发一次(最后停止时),所以在对scroll进行事件绑定判断时,需要通过setTimeout的方法不断判断当前scrollTop与旧的scrollTop的值是否一致,如果不一致则说明屏幕仍在滚动。实现代码如下:

        var count = 0, timer = null; 
        var oldTop = newTop = $(window).scrollTop(); //为了方便起见,使用jquery或者zepto框架
        function log(){
            if(timer) clearTimeout(timer);
            newTop = $(window).scrollTop();
            console.log(++count,oldTop,newTop);
            if(newTop === oldTop) {
                clearTimeout(timer);
                //已停止,写入业务代码
            } else{
                oldTop = newTop;
                timer = setTimeout(log,100);
            }        
        }
        $(window).on('scroll',log);        

然而忧桑的是,据说很多android的机型在触发scroll事件的时候,仍旧不能遵守规则按照正确的方式触发,所以如果我们监听scroll事件,仍旧有几率出bug,so结论是~~~~

 

三、结论

针对ipad和Android的滚动结束监听,其兼容性处理方案为:监听touchmove事件

来保证最好的兼容。即代码如下:

        var count = 0, timer = null; 
        var oldTop = newTop = $(window).scrollTop(); //为了方便起见,使用jquery或者zepto框架
        function log(){
            if(timer) clearTimeout(timer);
            newTop = $(window).scrollTop();
            console.log(++count,oldTop,newTop);
            if(newTop === oldTop) {
                clearTimeout(timer);
                //已停止,写入业务代码
            } else{
                oldTop = newTop;
                timer = setTimeout(log,100);
            }        
        }
        $(window).on('touchmove',log);  

这种方式由于过早的监听可能会损耗更多的性能,所以如果你只做ipad的话就监听scroll(或touchend);只做android就监听touchcancel。

相关文章: