基于zepto的左右地址选择插件

首先我们看看效果如下:


通过左右箭头可以选择一个特定的发货地址,我们可以看看dom结构:


其中Q_location是我们的包裹容器,通过它设置元素的大小,hwslide就是我们自己实例化的对象(但是必须在dom都插入完成后才能实例化),其宽度和高度都设置为100%就可以了。

第一步:我们可以看到方法其实是在每一个zepto实例上的

 $.fn.hwSlider = function(options) {
      //this为zepto对象
        var hwSlider = new HwSlider(this, options);
        //逐个元素调用init方法,init中的this是我们的HwSlider对象
        return this.each(function () {
            hwSlider.init();
        });
    };
注意: 我们必须在所有的DOM都构建完毕后才能实例化我们的HwSlide对象,否则可能存在元素高度没有计算完成的情况
第二步:我们看看实例化对象时候的options对象

var HwSlider = function(ele, opt){
        var self = this;
        self.$element = ele,
        self.defaults = {
            width: 480, //初始宽度
            height: 110, //初始高度
            start: 1, //初始滑动位置,从第几个开始滑动
            interval: 3000, //间隔时间,单位ms
            autoPlay: false,  //是否自动滑动
            //length表示滑块的个数,在后面代码中设置
            dotShow: false, //是否显示圆点导航
            arrShow: true, //是否显示左右方向箭头导航
            touch: true,//是否支持触摸滑动
            start:1//配置显示第一个,也就是下标是0的元素(这里表示是第几个,从1开始编号)
        },
        self.options = $.extend({}, self.defaults, opt)
    }

注意:上面的defaults对象都已经注明了

第三步:我们看看init中做了什么处理

 HwSlider.prototype = {
        init: function(){
            var self = this,
                ele = self.$element;
            var sliderInder = ele.children('ul')
            var hwsliderLi = sliderInder.children('li');
          //每一个li就是一个滑块
            var hwsliderSize = hwsliderLi.length;  //滑块的总个数
            self.options.length=hwsliderSize;//把滑块的个数放在options中
            //配置的start表示我们的index
            var index = self.options.start;
            var touchStartY = 0,touchStartX = 0;
            //指定显示index配置的滑块显示
            for(var i=1;i<=hwsliderSize;i++){
                if(index==i) {
                   hwsliderLi.eq(index-1).css('display','block');
                }
            }
           
            //显示左右方向键,我们传入的elem表示的是id为hwslider的元素
            if(self.options.arrShow){
                var arrElement = '<a href="javascript:;" id="pre" class="arr prev"><</a><a href="javascript:;" id="next" class="arr next">></a>';
                ele.append(arrElement);
            }

            //显示圆点导航
            if(self.options.dotShow){
                var dot = '';
                for(i=1;i<=hwsliderSize;i++){
                    if(index==i){
                        dot += '<span data-index="'+i+'" class="active"></span>';
                    }else{
                        dot += '<span data-index="'+i+'"></span>';
                    }
                }
                var dotElement = '<div class="dots">'+dot+'</div>';
                ele.append(dotElement);
            }

            //窗口大小发生变化的时候
            var load = function(){
                var sWidth = ele.width();
                //根据滑块宽度等比例缩放高度,也就是说保持宽高比不变
                var sHeight = self.options.height;
                ele.css('height',sHeight); 
                //设置箭头元素的显示top/left的值,其中sHeight表示元素的hwslider高度,40表示
                if(self.options.arrShow){
                    console.log('sHeight=',sHeight);
                    var arrOffset = (sHeight-40)/2;
                 
                    ele.find(".arr").css('top',arrOffset/75+'rem'); //导航箭头位置
                }
                //是否显示当前显示的元素
                if(self.options.dotShow){
                    var dotWidth = hwsliderSize*20;
                    var dotOffset = (sWidth-dotWidth)/2;
                    ele.find(".dots").css('left',dotOffset/75+'rem'); //导航圆点位置
                }
            }
            ele.css('height',self.options.height);
            //页面onload时候设置滑块的left/top,其实我们建议使用css来设置rem值来完成,而不用js控制
            load();
        
            //点击导航圆点
            if(self.options.dotShow){
                ele.find(".dots span").on('click',  function(event) {
                    event.preventDefault();
                    if(self.clickable){
                        var dotIndex = $(this).data('index');
                        if(dotIndex > index){
                            dir = 'next';
                        }else{
                            dir = 'prev';
                        }
                        if(dotIndex != index){
                            index = dotIndex;
                            self.moveTo(index, dir);
                        }
                    }
                });
            }
            //绑定箭头事件,点击可以是循环的地址展示
            if(self.options.arrShow){
                ele.find('.next').on('click', function(event) {
                    event.preventDefault();
                    if(index >= hwsliderSize){
                        // index = 1;
                        //通过设置为1,我们可以循环的,此处不要求循环
                        index=self.options.length;
                    }else{
                        index += 1;
                    }
                    //调用moveTo方法
                    self.moveTo(index,'next');
                });

                //点击左箭头
                ele.find(".prev").on('click', function(event) {
                    event.preventDefault();
                    if(index == 1){
                        index = hwsliderSize;
                    }else{
                        index -= 1;
                    }
                    self.moveTo(index,'prev');
                });
            }

            //自动滑动
            if(self.options.autoPlay){
                var timer;
                var play = function(){
                    index++;
                    if(index > hwsliderSize){
                        index = 1;
                    }
                    self.moveTo(index, 'next');
                }
                timer = setInterval(play, self.options.interval); //设置定时器
            };

            //触摸滑动
            if(self.options.touch){
                hwsliderLi.on({
                    //触控开始
                    'touchstart': function(e) {
                        touchStartY = e.touches[0].clientY;
                        touchStartX = e.touches[0].clientX;
                    },

                    //触控结束
                    'touchend': function(e) {
                        var touchEndY = e.changedTouches[0].clientY,
                            touchEndX = e.changedTouches[0].clientX,
                            yDiff = touchStartY - touchEndY,
                            xDiff = touchStartX - touchEndX; 
                        //判断滑动方向
                        if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {
                          //水平方向的滑动
                            if ( xDiff > 5 ) {
                              //对于tap事件,我们也是不允许循环显示的
                                if(index >= hwsliderSize){
                                    // index = 1;
                                    index=hwsliderSize;
                                }else{
                                    index += 1;
                                }
                                self.moveTo(index,'next');
                            } else {
                                if(index == 1){
                                    // index = hwsliderSize;
                                    index=1;
                                }else{
                                    index -= 1;
                                }
                                self.moveTo(index,'prev');
                            }                       
                        }
                        touchStartY = null;
                        touchStartX = null;
                    },

                    //触控移动
                    'touchmove': function(e) {
                        if(e.preventDefault) { e.preventDefault(); }

                    }
                });
            }
        },

        //滑动移动
        moveTo: function(index,dir){ 
            var self = this,
                ele = self.$element;
            var dots = ele.find(".dots span");
            var sliderInder = ele.children('ul');
            var hwsliderLi = sliderInder.children('li');
            //控制pre和next的隐藏
            var pre=document.getElementById('pre');
            var next=document.getElementById('next');
            //往左边的显示出来
            index==1?pre.style.display='none':pre.style.display="block";
            //已经到达最后,我们
            index==self.options.length?next.style.display="none":next.style.display='block';
            if(dir == 'next'){
                //当前滑块动画
                hwsliderLi.removeAttr('class').css('display','none');
                    // hwsliderLi.removeAttr('class').css('display','block');
                hwsliderLi.eq(index-2).addClass('moveout_right').css('display','block');
                
                //下一个滑块动画
                hwsliderLi.removeClass('active').eq(index-1).addClass('movein_right').css('display','block');
                
            }else{
                //当前滑块动画
                hwsliderLi.removeAttr('class').css('display','none');
                  // hwsliderLi.removeAttr('class').css('display','block');
                hwsliderLi.eq(index-3).addClass('moveout_left').css('display','block');
                //下一个滑块动画
                hwsliderLi.removeClass('active').eq(index-1).addClass('movein_left').css('display','block');
                
            }
            //self.clickable = true;
            //显示可切换的圆点
            dots.removeClass('active');
            dots.eq(index-1).addClass('active');
                
            
        }
        
    }

注意:我们很显然可以看到其原理和我们见到的滑动门效果是一样的,在此不多说,我们看看其中的touch事件:

if(self.options.touch){
                hwsliderLi.on({
                    //触控开始
                    'touchstart': function(e) {
                        touchStartY = e.touches[0].clientY;
                        touchStartX = e.touches[0].clientX;
                    },

                    //触控结束
                    'touchend': function(e) {
                        var touchEndY = e.changedTouches[0].clientY,
                            touchEndX = e.changedTouches[0].clientX,
                            yDiff = touchStartY - touchEndY,
                            xDiff = touchStartX - touchEndX; 
                        //判断滑动方向
                        if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {
                          //水平方向的滑动
                            if ( xDiff > 5 ) {
                              //对于tap事件,我们也是不允许循环显示的
                                if(index >= hwsliderSize){
                                    // index = 1;
                                    index=hwsliderSize;
                                }else{
                                    index += 1;
                                }
                                self.moveTo(index,'next');
                            } else {
                                if(index == 1){
                                    // index = hwsliderSize;
                                    index=1;
                                }else{
                                    index -= 1;
                                }
                                self.moveTo(index,'prev');
                            }                       
                        }
                        touchStartY = null;
                        touchStartX = null;
                    },

                    //触控移动
                    'touchmove': function(e) {
                        if(e.preventDefault) { e.preventDefault(); }

                    }
                });
            }
        }
注意:在touchstart中我们获取 touches列表,但是在touchend中我们获取 changedTouches集合,然后计算触点的变换的距离。
最后:我们看看如何实例化

 AddressListsDOM=`<span class='Q_close'></span>
	            <span class='Q_taokl'></span>
	            <p class='Q_description'>奖品标题文案奖品标题文案奖品标题文案奖品将寄送到以下地址,请选择确认</p>
	            <div class='Q_locations'>
	            <div id="hwslider" class="hwslider">
	             <ul>${AddressListsDOM}  </ul> 
	             </div> </div>
	             <span class='Q_max-button'>确定</span>
	             <p class="Q_warning">重要说明:<br>实物奖品寄送周期为15个工作日,请耐心等待哦!</p>`;
	          let QPopupMax=document.querySelector('#Q_popup_max');
	           QPopupMax.style.display='block';
	           QPopupMax.innerHTML=AddressListsDOM;
	           QMask.style.display='block';
	          //不是location调用的
	          $("#hwslider").hwSlider({
	            autoPlay: false,
	            dotShow: false,
	            touch: true
	         });
注意:是在dom都已经插入的时候才能调用hwSlide方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值