码迷,mamicode.com
首页 > Web开发 > 详细

js+css3模拟溢出滚动

时间:2016-08-11 17:40:26      阅读:309      评论:0      收藏:0      [点我收藏+]

标签:

声明:此程序仅针对手机端,简单的封装一个插件,意在记载插件的开发过程,如有错误及不足之处,还望即时指出。

        

        移动开发的时候,我们经常会遇到滑动事件,众所周知主要依靠touch事件。最近接连遇到两个页面都有类似overflow:auto的效果,一般情况下通过css设置是可以实现的(虽说丑了点儿),,但是一旦overflow:auto的元素响应touch事件时就会有诸多不便,例如fullpage中某一元素自滑动,我们可以通过normalScrollElements来使元素滑动的时候不滑动到下一屏,但是在元素滑动到最底部的时候也就不能响应下一屏事件,上滑也是一样,这时候就需要touch事件来响应,为了以后封装方便,特简单封装一个jquery插件,同时也复习一下jquery插件开发及touch事件;

          插件大体思路是这样的,如下图所示:方框内区域为固定宽高的父元素(设置overflow:hidden),子元素高度大于父元素,我们通过响应touch事件改变子元素的translate值(top也可以,但是translate效率更高一些),当然在此期间我们需判断子元素translate值的边界,最大为0,最小为子元素高度-父元素高度 

         ps:如果想做子元素根据手指移动,松开手指后回到边界需另写程序

技术分享      下面来一步步写插件

     第一步,先建立一个安全的作用域

;(function($){
//插入代码


})(jQuery)

 

     如果我们需要通过$(“#id”).xx()方法调用,需要像下面这样写,这里的fn及jquery的prototype;

      $.extend({

            exec:function(){}

      })    //这种扩展通过$.exec()调用

$.fn.simuScroll = function(option){
        var scrollObj=new simuScroll(this,option);
        return scrollObj.init();
}

   

   下面来看上面代码中的simuScroll方法,这是一个构造函数,它接受两个参数,ele为当前接受touch事件的元素(一般可以设置为父元素),option为用户传入的配置参数,如改变translate的元素,父元素子元素高度,extra为需额外增加的高度,滑动到顶部或底部时执行的回调函数等等;

var simuScroll = function(ele,option){
    this.settings = {
         target : ele,    //事件元素
         changeTarget:‘‘,
         outerHeight : ‘800‘,   //外层高度
         innerHeight : ‘500‘,   //内层高度
         extra : ‘0‘,           //额外增加的距离
         swipeUp : null,
         swipeDown : null,
         vertical:true
    };
    //通过jquery.extend对默认的settings进行扩展,得出一个全新的对象
    this.opt = jQuery.extend({},this.settings,option);        
    this.initNumber = this.lastNumber = this.result = 0;
    this.flag = false;
    //计算出子元素与父元素距离差,以此来判定元素的最大滑动距离
    this.diff = parseFloat(this.opt.innerHeight) - parseFloat(this.opt.outerHeight) + parseFloat(this.opt.extra);
    this.diff = this.diff < 0 ? 0 :this.diff;
    this.direction = ‘‘;
};

    

     在对jquery prototype进行扩展时,第一步为实例化上面的构造函数,第二步则直接调用了构造函数的init方法,具体见下面备注

init:function(){
            //jquery对象直接绑定touch事件获取event需originalEvent获取原生对象的event属性
            //jquery对象 获取pagex   event.originalEvent.touches[0].pageX   
            //dom对象  event.touches[0].pageX 
            var target = this.opt.target.get(0); 
            
            //如果子元素高度大于父元素,则执行滑动事件,否则执行回调函数
            this.flag = this.diff > 0 ? ‘translate‘ : ‘exec‘;
            
            /*如果元素已设置transform中 translate,scale,skew,rotate中的任何一项,
              则我们再直接设置transform:translateY(10px)时会覆盖掉初始设置的属性
              所以我们通过获取元素的matrix值既保证原有属性,又能设置任意值*/
            var cssText = this.opt.changeTarget.css(‘-webkit-transform‘);
            if(cssText==‘none‘){  //元素未设置transform属性
                this.str = this.opt.vertical ? ‘translateY‘ : ‘translateX‘ ;
            }else{
                this.str = cssText ;
                var reg = /-?\d+\.?\d*/g;  //正则表达式
                
                /*获取matrix中各参数
                  直接获取到的matrix值为类似matrix(1,0,0,1,0,0)
                  获取到的为[1,0,0,1,0,0]  这样我们就可以随意的修改某一个值
                  数组的第5项为元素的translateX值,第6项为translateY值 */
                this.params = this.str.match(reg);  
                this.matrix = this.opt.vertical ? 6 : 5 ; //根据传入的参数确定要修改的值为translateY或tranlateX
            }            
            var _this = this;
            
            //父元素绑定touch事件,传递事件对象及context
            target.addEventListener(‘touchstart‘,function(e){
                _this.start(e,_this)
            });
            target.addEventListener(‘touchmove‘,function(e){
                _this.move(e,_this)
            });
            target.addEventListener(‘touchend‘,function(e){
                _this.end(e,_this)
            });
        }

     

touchstart方法相对比较简单,根据需要滑动的方向记录手指接触屏幕时的初始值

start:function(e,context){
    e.preventDefault();
    var touches = e.touches[0];
    context.initNumber = context.opt.vertical ? touches.pageY : touches.pageX;
},

  

touchmove方法主要根据手指滑动距离动态改变元素css属性,让元素能够跟随手指进行移动

setNumber方法只有一句话:  this.params.splice(n-1,1,number)  根据传入的参数改变matrix数组

move:function(e,context){
    e.preventDefault();
    var touches = e.touches[0];
    number = context.opt.vertical ? touches.pageY : touches.pageX;
    
    //获取相对手指触碰屏幕的变化值
    var  delta = number - context.initNumber;
    if(context.flag == ‘translate‘){   //如果需要滑动
        context.result = context.lastNumber + delta;
        
        //设置滑动的最大值和最小值
        context.result = context.result > 0 ? 0 : context.result ;
        context.result = -context.result > context.diff ? -context.diff : context.result;
        
        //动态设置元素css属性
        if(context.matrix){
            switch (context.matrix) {
                case 6: 
                     context.setNumber(6,context.result)
                     break;
                case 5:
                     context.setNumber(5,context.result)
                     break;
            }
            context.opt.changeTarget.css(‘-webkit-transform‘,‘matrix(‘+context.params.join(‘,‘)+‘)‘)
        }else{
            context.opt.changeTarget.css(‘-webkit-transform‘,context.str+‘(‘+context.result+‘px)‘)
        }
    }
},

 

touchend则判断释放时是否需要执行回调函数

end:function(e,context){
    e.preventDefault();
    var touches = e.changedTouches[0];
    var number = context.opt.vertical ? touches.pageY : touches.pageX,
        n = number - context.initNumber;
        
    //当元素滑动距离大于10 并且最初元素translate值为0同时回调函数存在,则执行回调函数
    if(n>10 && context.lastNumber == 0 && context.opt.swipeDown){ 
        context.opt.swipeDown()
    }else if(n<-10 && context.lastNumber == -context.diff && context.opt.swipeUp){
        context.opt.swipeUp();
    }
    
    //将常量设为结果值,能保证多次连贯滑动
    context.lastNumber = context.result;
}

 

基本上一个简单的jQuery插件就完成了,框架如下

;(function($){
    var a = function(m,n){
        //函数内容

    };
    
    a.prototype = {
        init:function(){
            
        },
        start:function(){
            
        },
        move:function(){
            
        },
        end:function(){
            
        },
        setNumber:function(){
            
        }
    }
    
    $.fn.scrol = function(o){
        var obj = new a(this,o);
        return obj.init()
    }
    
})(jQuery)

 

调用时如下:

$(".outer").simuScroll({
    ‘outerHeight‘:$(".outer").height(),
    ‘innerHeight‘:$(‘.inner‘).height(),
    ‘changeTarget‘ : $(".inner"),
    ‘swipeUp‘ :function(){
        console.log(‘up‘)
    },
    ‘swipeDown‘ :function(){
        console.log(‘down‘)
    },
    vertical:true
})

 

js+css3模拟溢出滚动

标签:

原文地址:http://www.cnblogs.com/mopagunda/p/5761719.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!