移动前端--下拉刷新

<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>test</title> 
</head>
<body style="background-color: beige;">
    <div id="container" style="width:100%;border:solid 1px blue; transform:translate(0px,-61px)">
        <div style="height:50px; line-height:50px; text-align:center; width:100%; border:solid 1px red;">
            努力加载中...
        </div> 
        <div style="width:100%; line-height:30px;background-color:#F2F2F2; font-size:17px; font-family:'Adobe Garamond Pro'">
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能。
            在1995年时,由Netscape公司的Brendan Eich,在网景导航者浏览器上首次设计实现而成。因为Netscape与Sun合作,Netscape管理层希望它外观看起来像Java,因此取名为JavaScript。但实际上它的语法风格与Self及Scheme较为接近。[1]
            为了取得技术优势,微软推出了JScript,CEnvi推出ScriptEase,与JavaScript同样可在浏览器上运行。为了统一规格,因为JavaScript兼容于ECMA标准,因此也称为ECMAScript。

            JavaScript是一种属于网络的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。通常JavaScript脚本是通过嵌入在HTML中来实现自身的功能的。[3]
            是一种解释性脚本语言(代码不进行预编译)。[4]
            主要用来向HTML(标准通用标记语言下的一个应用)页面添加交互行为。[4]
            可以直接嵌入HTML页面,但写成单独的js文件有利于结构和行为的分离。[4]
            跨平台特性,在绝大多数浏览器的支持下,可以在多种平台下运行(如Windows、Linux、Mac、Android、iOS等)。
            Javascript脚本语言同其他语言一样,有它自身的基本数据类型,表达式和算术运算符及程序的基本程序框架。Javascript提供了四种基本的数据类型和两种特殊数据类型用来处理数据和文字。而变量提供存放信息的地方,表达式则可以完成较复杂的信息处理。[5]
        </div>

    </div>

</body>
</html>

JavaScript该做什么呢?  

    1、根据滑动轨迹动态调整滑块位置(transfrom=>translate);

    2、根据滑动的距离判断是否执行刷新(或数据加载)。

    当然,如果滑动结束后使用ajax重新加载页面数据,还将涉及到一个页面向上滑动并隐藏提示部分的效果。

    

    大致思路:

    (前提条件:当前元素已滑动至顶部) 

    1、当鼠标左键按下(移动设备上的touchstart事件)的时候记录下当前鼠标位置的 Y轴坐标;

    2、当鼠标移动的时候(touchmove事件),记录下鼠标的Y 轴坐标判断滑动轨迹并进行相应的滑块移动;

    3、当鼠标左键松开(touchend事件)的时候,通过对比鼠标开始和结束的Y轴坐标的距离判断是否应该刷新页面(或重新加载数据)。

/*
    *obj--滑动对象
    *offset--滑动距离(当滑动距离大于等于offset时将调用callback)
    *callback--滑动完成后的回调函数
    */
    var slide = function (obj, offset, callback) {
        var start,
            end,
            isLock = false,//是否锁定整个操作
            isCanDo = false,//是否移动滑块
            isTouchPad = (/hp-tablet/gi).test(navigator.appVersion),
            hasTouch = 'ontouchstart' in window && !isTouchPad;

        //将对象转换为jquery的对象
        obj = $(obj);

        var objparent = obj.parent();

        /*操作方法*/
        var fn =
            {
                //移动容器
                translate: function (diff) {
                    obj.css({
                        "-webkit-transform": "translate(0," + diff + "px)",
                        "transform": "translate(0," + diff + "px)"
                    });
                },
                //设置效果时间
                setTranslition: function (time) {
                    obj.css({
                        "-webkit-transition": "all " + time + "s",
                        "transition": "all " + time + "s"
                    });
                },
                //返回到初始位置
                back: function () {
                    fn.translate(0 - offset);
                    //标识操作完成
                    isLock = false;
                }
            };

        //滑动开始
        obj.bind("touchstart", function (e) {

            if (objparent.scrollTop() <= 0 && !isLock) {
                var even = typeof event == "undefined" ? e : event;
                //标识操作进行中
                isLock = true;
                isCanDo = true;
                //保存当前鼠标Y坐标
                start = hasTouch ? even.touches[0].pageY : even.pageY;
                //消除滑块动画时间
                fn.setTranslition(0);
            }
        });

        //滑动中
        obj.bind("touchmove", function (e) {

            if (objparent.scrollTop() <= 0 && isCanDo) {

                var even = typeof event == "undefined" ? e : event;

                //保存当前鼠标Y坐标
                end = hasTouch ? even.touches[0].pageY : even.pageY;

                if (start < end) {
                    even.preventDefault();
                    //消除滑块动画时间
                    fn.setTranslition(0);
                    //移动滑块
                    fn.translate(end - start - offset);
                }

            }
        });


        //滑动结束
        obj.bind("touchend", function (e) {
            if (isCanDo) {
                isCanDo = false;
                //判断滑动距离是否大于等于指定值
                if (end - start >= offset) {
                    //设置滑块回弹时间
                    fn.setTranslition(1);
                    //保留提示部分
                    fn.translate(0);

                    //执行回调函数
                    if (typeof callback == "function") {
                        callback.call(fn, e);
                    }
                } else {
                    //返回初始状态
                    fn.back();
                }
            }
        });
    }

JavaScript相关代码

1、参数:obj,要滑动的对象;offset,提示部分的transform的值(代码中是 transform:translate(0px,-61px) ,那么这里就是61);callback,回调函数,在下拉完成后调用的函数(页面刷新或数据加载)。

 2、为什么是transform不是margin? 

  因为transform不会引起重绘,相比margin更流畅,性能更好。但是transfrom有个比较好玩的地方,如果translateY的值为负数(当前元素上移xx像素)下方元素不会跟着上移(margin会上移),在这点上它和margin是有区别的。 注意,这里的-webkit-transform的存在是有必要的,因为有些浏览器识别不了transform,比如微信内置浏览(我的手机上是这样的)。为了兼容性,多扣几个字母是值得的。

 3、关于transition设置为0s。

  为什么要在touchstart的时候把transition的值设置为0秒呢?transition的作用是为元素属性的变化添加过渡效果,例如一个框变大,我们设置为transition为1s,那么这个框就是在1s内变大到指定大小。第一个参数表示设置过渡效果的 CSS 属性的名称(如:margin,transform;all表示所有),第二个参数表示过渡的时间。 代码中设置transition的目的是在于滑动结束后(手指离开屏幕)为滑块回弹添加过渡效果,这样看上去就不会那么突兀。当然,这个过渡效果同样会应用到数据加载完成后提示部分的隐藏上。设置为0是为了取消在滑动过程中的滑块过渡效果,我们手指往下滑动的时候,滑块会跟这向下移动,这样就有了滑动滑块的效果。如果这个时候不取消transition就会出现滑块抖动的效果(嘿嘿,有兴趣的话可以试试这种感觉。)。整个过程中transition是相当重要的。

 4、关于isLock和isCanDo.

   这两个变量的作用在于防止二次滑动,在第一次滑动后数据加载完成之前不允许有第二次的滑动。当滑动开始的时候讲isLock和isCanDo都设置为True,表示允许后面两个事件里的代码可以正常运行,当滑动结束后isCanDo设置为false表示在isLock被设置为True之前(整个操作完成之前)所有的事件代码均不可用(不执行下拉数据加载等相关动作)。

5、如何使用?

这个比较就简单,但也比较重要。

$(function () {

        slide("#container", 61, function (e) {
            var that = this;

            setTimeout(function () {
                that.back.call();
            }, 2000);

        });
    });

代码中的setTimeout是用于模拟ajax加载数据的效果,加载数据这部分就没有再单独写过了。JavaScript的回调函数是用着最顺手的特性之一。这里在数据加载完成后需要调用一个back方法,这个方法目的就是重置slide里的各种状态。

window.onload = function(){
				window.addEventListener('touchstart', touchstart, false);
				window.addEventListener('touchmove', touchMove, false);
			}
			
			var _start = 0; 
			var _end = 0;
			function touchstart(event) {
				var touch = event.targetTouches[0];
				_start = touch.pageY; 
			}
			function touchMove(event){ 
				var touch = event.targetTouches[0]; 
				_end = ( touch.pageY - _start); 
				//下滑才执行操作 
				if(_end > 200){     //200即手机下滑屏幕的距离,超过200则执行刷新动作
					location.reload();
				} 
			} 

猜你喜欢

转载自blog.csdn.net/qq_40001322/article/details/82186148