手機觸摸滑動框架 — Swipe.js 源代碼全解析

jsjavascript

window.Swipe = function(element, options) {
    if (!element) return null;
    var _this = this;  //緩存this
    this.options = options || {}; //接受配置
    this.index = this.options.startSlide || 0; //幻燈片索引
    this.speed = this.options.speed || 300; //移動速度
    this.callback = this.options.callback || function() {};  //回掉函數
    this.delay = this.options.auto || 0; //延遲執行
    this.CustomDistance = this.options.Distance || 0; // 自定義距離 屏幕的寬度減去此距離
    this.container = element;  //swipe
    this.element = this.container.children[0];  //swipe-wrap
    this.container.style.overflow = 'hidden';
    this.element.style.listStyle = 'none';
    this.element.style.margin = 0;
    this.setup();  //設置幻燈片
    this.begin();  //開始執行
     
    if (this.element.addEventListener) {  //監聽各類
        this.element.addEventListener('touchstart', this, false);  //觸摸開始
        this.element.addEventListener('touchmove', this, false);  //觸摸時
        this.element.addEventListener('touchend', this, false);  //觸摸結束
        this.element.addEventListener('webkitTransitionEnd', this, false); //動畫結束時觸發 webkit專用
        this.element.addEventListener('msTransitionEnd', this, false); //動畫結束時觸發 ie專用
        this.element.addEventListener('oTransitionEnd', this, false); //動畫結束時觸發 Opera 專用
        this.element.addEventListener('transitionend', this, false); //動畫結束時觸發 公用
        window.addEventListener('resize', this, false) //窗口改變時
    }
};
Swipe.prototype = {
    setup: function() {
        console.log(this);
        this.slides = this.element.children; //獲取幻燈片div
        this.length = this.slides.length;  //獲取幻燈片div的數量
        if (this.length < 2) return null;  //當只有一個幻燈片的時候直接返回
 
        //getBoundingClientRect這個方法返回一個矩形對象,包含四個屬性:left、top、right和bottom。分別表示元素各邊與頁面上邊和左邊的距離。
        this.width = ("getBoundingClientRect" in this.container) ? this.container.getBoundingClientRect().width: this.container.offsetWidth;  //獲取寬度
 
        if (!this.width) return null;  //如過獲取不到寬度 直接返回
        this.container.style.visibility = 'hidden';  //整個div不讓顯示 爲了設置下面的屬性 設置好後 再顯示
        this.element.style.width = (this.slides.length * this.width - (this.CustomDistance * this.slides.length)) + 'px'; //設置中間框的距離爲裏面幻燈片寬度的綜合
        var index = this.slides.length;  //設置個循環 循環次數爲幻燈片的數量
        while (index--) {  //開始循環
            var el = this.slides[index]; //獲取單個幻燈片
            el.style.width = this.width - this.CustomDistance + 'px';  // 它的寬度
            el.style.display = 'table-cell';  //加上表格佈局屬性
            el.style.verticalAlign = 'top'  //頂部排列
        };
        this.slide(this.index, 0);  //執行slide方法
        this.container.style.visibility = 'visible'
    },
    slide: function(index, duration) {  //接受兩個參數 幻燈片的位置索引,移動的速度
        var style = this.element.style;
        if (duration == undefined) {
            duration = this.speed  //移動速度
        };
        style.webkitTransitionDuration = style.MozTransitionDuration = style.msTransitionDuration = style.OTransitionDuration = style.transitionDuration = duration + 'ms';  //設置css3過渡的動畫速度
        style.MozTransform = style.webkitTransform = 'translate3d(' + -(index * (this.width - this.CustomDistance)) + 'px,0,0)';  //火狐和谷歌加上 Transform屬性
        style.msTransform = style.OTransform = 'translateX(' + -(index * (this.width - this.CustomDistance)) + 'px)';  //ie和opera加上 Transform屬性
        this.index = index; //設置幻燈片的索引
    },
    getPos: function() {
        return this.index; //獲取幻燈片的索引
    },
    prev: function(delay) {   //往上滑
        this.delay = delay || 0;  //更新延遲
        clearTimeout(this.interval);  //清除延時
        if (this.index) this.slide(this.index - 1, this.speed)  //執行slide 進行動畫
    },
    next: function(delay) {  //往下滑同上
        this.delay = delay || 0;
        clearTimeout(this.interval);
        if (this.index < this.length - 1) this.slide(this.index + 1, this.speed);
        else this.slide(0, this.speed)
    },
    begin: function() {
        var _this = this;
        this.interval = (this.delay) ? setTimeout(function() {
            _this.next(_this.delay)
        },this.delay) : 0 //延遲執行的索引 如過沒有延遲 返回0
    },
    stop: function() {  //中止動畫
        this.delay = 0;
        clearTimeout(this.interval)
    },
    resume: function() {  //是否自動執行
        this.delay = this.options.auto || 0;
        this.begin()
    },
    handleEvent: function(e) {  //獲取type值 根據type值執行相應的函數
        switch (e.type) {
        case 'touchstart': 
            this.onTouchStart(e);  //觸摸開始
            break;
        case 'touchmove':
            this.onTouchMove(e);  //觸摸時
            break;
        case 'touchend':
            this.onTouchEnd(e);  //觸摸結束
            break;
        case 'webkitTransitionEnd':
        case 'msTransitionEnd':
        case 'oTransitionEnd':
        case 'transitionend':
            this.transitionEnd(e);  //動畫結束時執行
            break;
        case 'resize':
            this.setup();  //窗口變換時執行
            break
        }
    },
    transitionEnd: function(e) {
        if (this.delay) this.begin();  //動畫結束時判斷是否再次執行 這步是判斷自動執行的關鍵所在
        this.callback(e, this.index, this.slides[this.index])  //執行結束時的回調函數 返回even對象,當前的幻燈片索引,當前幻燈片的對象
    },
    onTouchStart: function(e) {
        this.start = {  //記錄剛開始的更重數值 x y 和 時間
            pageX: e.touches[0].pageX,
            pageY: e.touches[0].pageY,
            time: Number(new Date())
        };
        this.isScrolling = undefined;  //設置個屬性 目的在move時 isScrolling只計算一次
        this.deltaX = 0;
        this.element.style.MozTransitionDuration = this.element.style.webkitTransitionDuration = 0;  //先把動畫的值設置爲0
         
    },
    onTouchMove: function(e) {
        if (e.touches.length > 1 || e.scale && e.scale !== 1) return;  //如過是兩根以上的手指 或者是 窗口縮放了 那就直接返回
        this.deltaX = e.touches[0].pageX - this.start.pageX;   //計算移動X軸的距離
        if (typeof this.isScrolling == 'undefined') {  
            this.isScrolling = !!(this.isScrolling || Math.abs(this.deltaX) < Math.abs(e.touches[0].pageY - this.start.pageY))  //如過Y軸的傾向大於X軸的傾向也不賦值
        };
        if (!this.isScrolling) {
            e.preventDefault();  //若是是左右滑動則阻止默認事件以防止安卓move只執行一次的問題
            clearTimeout(this.interval);
            this.deltaX = this.deltaX / ((!this.index && this.deltaX > 0 || this.index == this.length - 1 && this.deltaX < 0) ? (Math.abs(this.deltaX) / this.width + 1) : 1);
            this.element.style.MozTransform = this.element.style.webkitTransform = 'translate3d(' + (this.deltaX - this.index * (this.width - this.CustomDistance)) + 'px,0,0)';
             
        }
    },
    onTouchEnd: function(e) {
        var isValidSlide = Number(new Date()) - this.start.time < 250 && Math.abs(this.deltaX) > 20 || Math.abs(this.deltaX) > this.width / 2,
        isPastBounds = !this.index && this.deltaX > 0 || this.index == this.length - 1 && this.deltaX < 0;
        if (!this.isScrolling) {
            this.slide(this.index + (isValidSlide && !isPastBounds ? (this.deltaX < 0 ? 1 : -1) : 0), this.speed)  //執行動畫
        };
         
    }
}; 
window.addEventListener('load', function() {
    setTimeout(scrollTo, 0, 0, 1);
}
, false);

htmlcss

     <SCRIPT type=text/javascript src="images/fpic.js"></SCRIPT>
     <div class="mpic" id="mpic">
            <ul>
                <% foreach(DataRow dr in WebInfo.GetLinkTop(3,5).Rows)
                   { %>
      <li><a href="<%=dr["linkurl"] %>"><img src="<%=imgurl+dr["picpath"] %>" /></a></li>
                <%} %>
    
             </ul>
             <div class="mpic_btn" id="mpic_btn"></div>
           </div>

     <script type="text/javascript">
       for(i=0; i<$("#mpic ul li").length;i++){ $("#mpic_btn").append("<span></span>"); }
    $("#mpic_btn span").eq(0).addClass("on");
    var slider = new Swipe(document.getElementById('mpic'), {
        speed: 500,
        auto: 3000,
        callback: function (e, pos) {
            var i = bullets.length;
            while (i--) {
                bullets[i].className = ' ';
            }
            bullets[pos].className = 'on';
        }
    });
    bullets = document.getElementById('mpic_btn').getElementsByTagName('span');
        </script>

https://github.com/Nordis/Swipehtml

相關文章
相關標籤/搜索