Zhiqim UI是一套集成Javascript库、Css库、Font库、常用ico图标等,并在其上开发的大量UI组件组成的前端开发套件。

森中灵 最后提交于11月前 整理V8.0.6
zhiqim_slider.mobile.js11KB
/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙,邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_ui.htm
 *
 * Zhiqim UI is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
+(function(Z)
{

/****************************************/
//“轮播图”
/****************************************/
Z.Slider = Z.Class.newInstance();
Z.Slider.prototype = 
{
    defaults: 
    {//定义
        elem: '',              // 主容器
        rectRatio: 2,          // 宽度比例
        playAuto: true,        // 设定自动滚动
        playSpeed: 2000,       // 播放间隔
        transDur: 300,         // 动画时长
        transFun: "ease",      // 动画轨迹
    },
    init: function()
    {//初始化
    },
    execute: function()
    {//执行
        //1:重新组装排版
        this.$touch = Z.$elem(this.elem, "Z.Slider").addClass("z-slider-touch");
        
        this.$wrap = Z('<div class="z-slider z-bg-gray z-text-center"></div>').insertAfter(this.$touch);
        this.$wrap.append(this.$touch);
        this.$tab = Z('<div class="z-slider-tab"></div>').appendTo(this.$wrap);
        this.$$items = this.$touch.children("li");
        
        //2:基本参数
        this.width = this.$wrap.offsetWidth();
        this.height = this.width/this.rectRatio;
        this.length = this.$$items.length;
        if (this.rectRatio < 0){
            this.rectRatio = 2;
        }
        if (this.playSpeed < this.transDur){
            this.playSpeed = this.transDur;
        }
        
        //3:插入展示按钮html
        var btnsHtml = "";
        for(var i = 0;i < this.length;i++){
            btnsHtml += '<span></span>';
        }
        this.$tab.html(btnsHtml);
        this.$$tabs = this.$tab.children("span");
        
        //4:初始化样式、位置
        this.$wrap.css("height",this.height);
        
        if (this.length <= 1)
        {/*一张图片时*/
            return;
        }
        
        if (this.length == 2)
        {/*两个滚动素材的情况*/
            this.$touch.css("transition-timing-function",this.transFun).css("transition-duration",this.transDur+"ms")
                .css("transform","translate3d(0,0,0)");
            
            Z(this.$$items[0]).css("transform","translate3d(0,0,0)").addClass("z-active");
            Z(this.$$items[1]).css("transform","translate3d("+this.width+"px,0,0)");
            
            //要实现无缝滚动,需复制节点
            this.$firstClone = Z(this.$$items[0].cloneNode(true)).appendTo(this.$touch);
            this.$lastClone = Z(this.$$items[1].cloneNode(true)).appendTo(this.$touch);
            this.$firstClone.css("transform","translate3d("+2*this.width+"px,0,0)");
            this.$lastClone.css("transform","translate3d(-"+this.width+"px,0,0)");
            
            //动画结束,位置调整
            this.$touch.on(this.transitionFixed(), this.doubleSlideEnd, this);
        }
        else
        {/*两张以上滚动素材的情况*/
            this.$$items.css("transition-timing-function",this.transFun).css("transition-duration",this.transDur+"ms");
            var that = this;
            Z.each(this.$$items, function($item,index){
                var translateX = index * that.width + "px";
                if (index == 0) {
                    Z($item).addClass("z-active");
                }
                if (index == that.length - 1) {
                    translateX = -that.width + "px";
                }
                Z($item).css("transform","translate3d("+translateX+",0,0)");
            });
        }
        Z(this.$$tabs[0]).addClass("z-active");
        
        //5:滑动事件绑定
        this.touchmoving = false;
        this.$touch.on("touchstart",this.touchStart,this);
        this.$touch.on("touchmove",this.touchMove,this);
        this.$touch.on("touchend",this.touchEnd,this);
        
        //6:开始执行动画
        this.autoPlay();
    },
    autoPlay: function()
    {
        if(this.playAuto){
            var that = this;
            that.timer = setInterval(function(){
                that.sliderNext(that);
            },that.playSpeed);
        }
    },
    touchStart:function(ev)
    {//触摸事件开始
        Z.E.forbidden(ev);
        var touch = ev.touches[0];
        this.touchStartX = touch.pageX;
        
        //清除自动
        clearInterval(this.timer);
        
        //两个滚动素材的情况
        if (this.length == 2){
            var step = +step;
            var $activeItem = this.$touch.find(".z-active");
            var activeIndex = Z.AR.indexOf(this.$$items, $activeItem[0]);
            this.touchBase = -activeIndex*this.width;
            this.$touch.css("transition-property","none");
            return;
        }
        
        //当前、前一个、后一个
        this.$activeItem = this.$touch.find(".z-active");
        var activeIndex = Z.AR.indexOf(this.$$items, this.$activeItem[0]);
        this.$activeNext = Z(this.$$items[activeIndex + 1] || this.$$items[0]);
        this.$activePrev = Z(this.$$items[activeIndex - 1] || this.$$items[this.length - 1]);
        
        //清除transition
        this.$activeItem.css("transition-duration","0ms");
        this.$activeNext.css("transition-duration","0ms");
        this.$activePrev.css("transition-duration","0ms");
    },
    touchMove: function(ev)
    {//滑动中
        if(this.touchmoving == false){
            this.touchmoving = true;
        }
        Z.E.forbidden(ev);
        var touch = ev.touches[0];
        this.touchMoveX = touch.pageX;
        
        //设置translate
        var metabolicX = this.touchMoveX - this.touchStartX;
        
        //两个滚动素材的情况
        if (this.length == 2){
            this.$touch.css("transform","translate3d("+(metabolicX+this.touchBase)+"px,0,0)");
            return;
        }
        
        this.$activeItem.css("transform","translate3d("+metabolicX+"px,0,0)");
        this.$activeNext.css("transform","translate3d("+(metabolicX + this.width)+"px,0,0)");
        this.$activePrev.css("transform","translate3d("+(metabolicX - this.width)+"px,0,0)");
    },
    touchEnd: function(ev)
    {//触摸事件结束
        if (this.touchmoving == false){
            return;
        }
        this.touchmoving = false;
        Z.E.forbidden(ev);
        
        //执行自动
        this.autoPlay();
        
        //判断滑动结果
        var metabolicX = this.touchMoveX - this.touchStartX;
        
        if (metabolicX == 0 || Math.abs(metabolicX) < this.width/2){
            this.sliderStay();
            return;
        }
        
        if (this.$activeItem) this.$activeItem.css("transition-duration",this.transDur+"ms");
        if (metabolicX < 0){
            if (this.$activeNext) this.$activeNext.css("transition-duration",this.transDur+"ms");
            this.sliderNext();
        } else {
            if (this.$activePrev) this.$activePrev.css("transition-duration",this.transDur+"ms");
            this.sliderPrev();
        }
    },
    sliderNext: function()
    {//后一个展示
        if (this.length == 2){
            this.doubleSlide(1);
            return;
        }
        this.sliderPlay(1);
    },
    sliderStay: function ()
    {//保持展示
        if (this.length == 2){
            this.doubleSlide(0);
            return;
        }
        this.sliderPlay(0);
    },
    sliderPrev: function()
    {//前一个展示
        if (this.length == 2){
            this.doubleSlide(-1);
            return;
        }
        this.sliderPlay(-1);
    },
    sliderPlay: function(step)
    {//滑动方法        
        var step = +step;
        var $activeItem = this.$touch.find(".z-active");
        var activeIndex = Z.AR.indexOf(this.$$items, $activeItem[0]);
        $activeItem.removeClass("z-active");
        
        //即将展示对象的索引值
        var shouldIndex = activeIndex + step;
        if (shouldIndex >= this.length) shouldIndex = 0;
        if (shouldIndex <= -1) shouldIndex = this.length - 1;
        
        //即将新定位的active,以及前后两个
        var $shouldActive = Z(this.$$items[shouldIndex]);
        var $shouldNext = Z(this.$$items[shouldIndex + 1] || this.$$items[0]);
        var $shouldPrev = Z(this.$$items[shouldIndex - 1] || this.$$items[this.length - 1]);
        
        //touch item新定位
        $shouldActive.addClass("z-active").css("transform","translate3d(0,0,0)")
            .css("transition-duration",this.transDur+"ms");
        $shouldNext.css("transform","translate3d("+this.width+"px,0,0)");
        $shouldPrev.css("transform","translate3d(-"+this.width+"px,0,0)");
        
        //前后两个判断是否动画
        var nextDur = prevDur = this.transDur+"ms";
        if (step > 0){ nextDur = "0ms";}
        else if(step < 0){ prevDur = "0ms";}
        $shouldNext.css("transition-duration",nextDur);
        $shouldPrev.css("transition-duration",prevDur);
        
        //btn 展示
        Z(this.$$tabs[shouldIndex]).addClass("z-active")
            .siblings("span").removeClass("z-active");
    },
    doubleSlide: function(step)
    {//两个滚动素材的动画
        var step = +step;
        var $activeItem = this.$touch.find(".z-active");
        var activeIndex = Z.AR.indexOf(this.$$items, $activeItem[0]);
        $activeItem.removeClass("z-active");
        
        var num = shouldIndex = activeIndex + step;
        if (shouldIndex >= this.length) shouldIndex = 0;
        if (shouldIndex <= -1) shouldIndex = this.length - 1;
        Z(this.$$items[shouldIndex]).addClass("z-active");
        
        this.$touch.css("transform", "translate3d("+(-num*this.width)+"px,0,0)")
            .css("transition-property","transform");
        
        //btn 展示
        Z(this.$$tabs[shouldIndex]).addClass("z-active")
            .siblings("span").removeClass("z-active");
    },
    doubleSlideEnd: function()
    {//两图片的滚动结束
        var $activeItem = this.$touch.find(".z-active");
        var activeIndex = Z.AR.indexOf(this.$$items, $activeItem[0]);
        this.$touch.css("transition-property","none");
        if(activeIndex == 0){
            this.$touch.css("transform", "translate3d(0,0,0)");
        }
        if(activeIndex == 1){
            this.$touch.css("transform", "translate3d("+(-this.width)+"px,0,0)");
        }
    },
    transitionFixed: function()
    {//兼容写法
        var $div = document.createElement('div');
        if ($div.style["transition"] !== undefined ){
            $div = null;
            return "transitionend";
        }
        if ($div.style["OTransition"] !== undefined ){
            $div = null;
            return "oTransitionEnd";
        }
        if ($div.style["WebkitTransition"] !== undefined ){
            $div = null;
            return "webkitTransitionEnd";
        }
    },
    //end of Z.Slider.prototype
}

//END
})(zhiqim);