親手設計及實現支持觸屏的jquery相冊插件

1、設計目標:設計一個可以支持觸屏左右滑動的循環相冊。

2、設計思路:將圖片橫向排放到一個框中。關鍵問題出在循環設計上。

因爲當相冊播放到第一張時,點上一張按鈕或向右滑動這時應該播放相冊的最後一張,並且要保持視覺上的連續性。

同裏在相冊最後一張向左滑動或點下一張按鈕也有同樣的問題。

3、如何解決循環?

辦法如下圖

紅框代表相冊,數字1代表的是第一張圖片,數字n代表的是最後一張圖片。

當從第二張圖片的1向右滑動至第一張圖片1時立即跳轉到倒數第二張圖片的n。

同理當從倒數第二張圖片的n向左滑動至最後一張圖片1時,立即跳轉到第二張圖片的1。


插件代碼實現如下。

/*
* jQuery Mobile Framework : "gallery" plugin
*
* author: codec007
* date  : 20150106
* email : [email protected]
* 
* example:
*
*           $("#album").gallery({
*                width: 270,
*                height: 202,
*                currnetPage: 0,
*                interval: 5000,
*                showButtons: true,
*                autoStart: true,
*                ButtonsID: "#buttons",
*                previousID: '#Left_button',
*                nextID: '#Right_button',
*                onChange: function (index, total) {
*                    var item = $($('[data-role="pictures"] > ul >li')[index]);
*                    $("#title1").text(item.attr("data-title"));
*                    $("#title2").text(item.attr("data-info"));
*                }
*           });
*           $.fn.gallery.goFirst();
*
*
*/
(function ($) {
    $.fn.gallery = function (options) {

        $.fn.gallery.defaults = $.extend({}, $.fn.gallery.defaults, options);
        $.fn.gallery.defaults.$this = this;

        var $this = this,
            gallery = $.fn.gallery,
            defaults = gallery.defaults;

        defaults.moveLocked = false;

        /*觸屏*/
        defaults.isTouchPad = (/OS 5_/gi).test(navigator.appVersion),
        defaults.hasTouch = 'ontouchstart' in window && !defaults.isTouchPad,
        defaults.pictureCount = $this.find("ul li").length;

        //添加循環播放
        var pictures = $this.find('> ul');
        var first = $this.find("> ul > li").first().clone();
        var last = $this.find("> ul > li").last().clone();
        pictures.prepend(last);//最後一張複製到第一張
        pictures.append(first);//第一張複製到最後一張

        //添加縮略點
        if (defaults.showButtons) {
            var $buttons = $(defaults.ButtonsID);
            var nav = $('<nav class="Buttons"></nav>');
            for (var i = 0; i <= defaults.pictureCount - 1; i++)
                $('<div' + (i == 0 ? ' class="GalleryCurrnetButton"' : '') + '></div>').appendTo(nav);
            nav.appendTo($buttons);
        }

        //自動調整
        $.fn.gallery.resize();

        //綁定觸屏事件
        var startEv = defaults.hasTouch ? 'touchstart' : 'mousedown',
            moveEv = defaults.hasTouch ? 'touchmove' : 'mousemove',
            endEv = defaults.hasTouch ? 'touchend' : 'mouseup',
            cancelEv = defaults.hasTouch ? 'touchcancel' : 'mouseup';

        $this.each(function (index, element) {
            element.addEventListener(moveEv, function (e) {
                gallery._touchMove(e, $this);
            }, false);
            element.addEventListener(startEv, function (e) {
                gallery._touchDown(e, $this);
            }, false);
            element.addEventListener(endEv, function (e) {
                gallery._touchUp(e, $this);
            }, false);
        });

        //前進
        if (defaults.nextID != "" && defaults.nextID != null)
            $(defaults.nextID).click(function () {
                gallery.goNext();
                if (defaults.autoStart)
                    gallery.resetTimer();
            });
        //後退
        if (defaults.previousID != "" && defaults.nextID != null)
            $(defaults.previousID).click(function () {
                gallery.goPrevious();
                if (defaults.autoStart)
                    gallery.resetTimer();
            });
        //變動
        $(window).bind('resize', function () {
            $.fn.gallery.resize();
        });

        //啓動時鐘
        if (defaults.autoStart)
            gallery.startTimer($this);

        return $this;
    };

    //自動調整
    $.fn.gallery.resize = function () {
        //應用內部元素樣式
        var $this = $.fn.gallery.defaults.$this;
        var defaults = $.fn.gallery.defaults;
        $.fn.gallery.defaults.width = $this.width();
        $this.find("ul").css({
            'left': -defaults.width,
            'width': defaults.width * (defaults.pictureCount + 2)
        });

        $this.find("> ul > li").css({ 'width': defaults.width, 'height': defaults.height });
        $this.css({ 'width': defaults.width, 'height': defaults.height });
    };

    //自動播放
    $.fn.gallery.autoPlay = function () {
        //var defaults = $.fn.gallery.defaults;
        //if (defaults.currnetPage == defaults.pictureCount - 1)
        //    $.fn.gallery.goFirst();
        //else
        //    $.fn.gallery.goNext();
    };

    //向前一張
    $.fn.gallery.goPrevious = function (dragXLength) {
        var defaults = $.fn.gallery.defaults;

        if (defaults.moveLocked) return;

        if (defaults.currnetPage > 0) {
            --defaults.currnetPage;
        }
        else {
            $.fn.gallery.goLast(dragXLength);
        }
        $.fn.gallery.go(defaults.currnetPage);
    };

    //向後一張
    $.fn.gallery.goNext = function (dragXLength) {
        var defaults = $.fn.gallery.defaults;

        if (defaults.moveLocked) return;

        if (defaults.currnetPage < defaults.pictureCount - 1) {
            ++defaults.currnetPage;
        }
        else {
            $.fn.gallery.goFirst(dragXLength);
        }
        $.fn.gallery.go(defaults.currnetPage);
    };

    //跳轉第一張
    $.fn.gallery.goFirst = function (dragXLength) {
        var defaults = $.fn.gallery.defaults;
        var $this = defaults.$this;
        var offset = 0;
        if (defaults.moveLocked) return;

        if (dragXLength) offset += dragXLength;
        

        $this.find("> ul").css('left', offset);

        var defaults = $.fn.gallery.defaults;
        defaults.currnetPage = 0;
        $.fn.gallery.go(defaults.currnetPage);
    };

    //跳轉最後一張
    $.fn.gallery.goLast = function (dragXLength) {
        var defaults = $.fn.gallery.defaults;
        var $this = defaults.$this;
        var offset =  -(defaults.pictureCount + 1) * defaults.width;

        if (defaults.moveLocked) return;

        if (dragXLength) offset += dragXLength;

        $this.find("> ul").css('left', offset);

        var defaults = $.fn.gallery.defaults;
        defaults.currnetPage = defaults.pictureCount - 1;
        $.fn.gallery.go(defaults.currnetPage);
    };

    //啓動計時器
    $.fn.gallery.startTimer = function ($this) {
        var defaults = $.fn.gallery.defaults;
        defaults.timer = setInterval(function () {
            $.fn.gallery.autoPlay($this);
        }, defaults.interval);
    };

    $.fn.gallery.stopTimer = function ($this) {
        clearInterval($.fn.gallery.defaults.timer);
    };

    //重置計時器
    $.fn.gallery.resetTimer = function () {
        var gallery = $.fn.gallery;
        gallery.stopTimer();
        gallery.startTimer();
    };

    //啓動暫停時鐘
    $.fn.gallery.startTouchDownTimer = function ($this) {
        var defaults = $.fn.gallery.defaults;
        defaults.dragTime = 0;
        defaults.touchDownTimer = setInterval(function () { defaults.dragTime++; }, 1);
    };

    //跳轉幀
    $.fn.gallery.go = function (pageNumber) {

        var defaults = $.fn.gallery.defaults;
        var $this = defaults.$this;

        if (defaults.moveLocked) return;
        defaults.moveLocked = true;

        if (pageNumber < 0) pageNumber = 0;
        if (pageNumber > defaults.pictureCount - 1)
            pageNumber = defaults.pictureCount - 1;

        if (defaults.showButtons) {
            //按鈕着色
            $(defaults.ButtonsID).find(".GalleryCurrnetButton").removeClass("GalleryCurrnetButton");
            $(defaults.ButtonsID).find(".Buttons div:eq(" + pageNumber + ")").addClass("GalleryCurrnetButton");
        }

        //滾動圖片
        $this.find("> ul").animate({ left: defaults.width * -(pageNumber + 1) }, 250, function () {defaults.moveLocked = false;});

        //激活事件
        defaults.onChange(pageNumber, defaults.pictureCount);
    };

    //綁定移動事件
    $.fn.gallery._touchMove = function (e, $this) {
        var defaults = $.fn.gallery.defaults;
        var point = defaults.hasTouch ? e.touches[0] : e;
        if (defaults.isDown) {
            var movex = point.pageX - defaults.touchDownX; //x滑動距離
            var movey = point.pageY - defaults.touchDownY; //y滑動距離
            //橫向水平滑動小於垂直滑動
            if (Math.abs(movex) > Math.abs(movey))
                e.preventDefault();
            $this.find("> ul").css('left', -(defaults.currnetPage+1) * defaults.width + movex); //左右滑動
        }
    };

    //綁定按下事件
    $.fn.gallery._touchDown = function (e, $this) {
        var defaults = $.fn.gallery.defaults;
        clearInterval(defaults.timer); //時鐘
        $.fn.gallery.startTouchDownTimer($this); //點擊計時器開始
        var point = defaults.hasTouch ? e.touches[0] : e;

        defaults.isDown = true;
        defaults.touchDownX = point.pageX;
        defaults.touchDownY = point.pageY;
    };

    //綁定放開事件
    $.fn.gallery._touchUp = function (e, $this) {
        var gallery = $.fn.gallery;
        var defaults = gallery.defaults;

        if (defaults.autoStart)
            clearInterval(defaults.timer);
        clearInterval(defaults.touchDownTimer); //停止時鐘

        var point = defaults.hasTouch ? e.changedTouches[0] : e;

        var dragXLength = point.pageX - defaults.touchDownX; //拖動距離x

        if (defaults.dragTime < 500 && dragXLength == 0)//點擊圖片
        {
            var url = $($this.element).find("img:eq(" + defaults.currnetPage + ")").attr("data-href");
            if (url)
                window.location.href = url;
        }
            //快速滑動下一個
        else if (defaults.dragTime < 50 && dragXLength < -17) {
            gallery.goNext(dragXLength);
        }
            //快速滑動上一個
        else if (defaults.dragTime < 50 && dragXLength > 17) {
            gallery.goPrevious(dragXLength);
        }
            //普通滑動
        else if (dragXLength < defaults.width / 2.5 * -1) {
            gallery.goNext(dragXLength);
        }
            //普通滑動上一個
        else if (dragXLength > defaults.width / 2.5) {
            gallery.goPrevious(dragXLength);
        } else {
            gallery.go(defaults.currnetPage);
        }
        defaults.isDown = false;
        defaults.ylock = false;

        if (defaults.autoStart)
            gallery.startTimer($this); //啓動時鐘
    };

    //插件預設值
    $.fn.gallery.defaults = {
        width: 320,
        height: 180,
        currnetPage: 0,
        interval: 5000,
        showButtons: false,
        autoStart: false,
        nextID: '',
        previousID: '',
        onChange: function (index, total) { }
    };
})(jQuery);


代碼調用示例

<!DOCTYPE html>
<html lang="zh-cn" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    <link href="./CSS/jquery.album.css" rel="stylesheet" />
    <style type="text/css">
        [data-role="pictures"] {
            display: block;
            border-radius: 11px;
            width: 520px;
            height: 280px;
            position: relative;
            overflow:hidden;
        }

            [data-role="pictures"] > ul {
                position: absolute;
                padding: 0;
                margin:0;
                display: block;
            }

                [data-role="pictures"] > ul > li {
                    position: relative;
                    display: block;
                    float: left;
                }

            [data-role="pictures"] img {
                width: 520px;
                height: 280px;
                display: block;
                box-sizing: border-box;
            }

        [data-role="gallery"] {
            overflow: hidden;
        }

        .Buttons {
            position:relative;
            right: 0px;
            bottom: 0px;
            width: 80px;
            height: 30px;
            color: white;
        }

            .Buttons div {
                position: relative;
                cursor: pointer;
                float: left;
                margin: 0px 1px 0px 1px;
                width: 10px;
                height: 10px;
                border-radius: 5px;
                background-color: #ffffff;
                background-color: gray;
            }

        .Buttons div.GalleryCurrnetButton {
            background-color: #e94900;
            background-color: red;
        }
    </style>
    <script type="text/javascript" src="./Javascript/jquery-1.11.1.min.js"></script>
    <script type="text/javascript" src="./Javascript/jquery.album.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#album").gallery({
                width: 520,
                height: 280,
                showButtons: true,
                autoStart: true,
                ButtonsID: "#buttons",
                previousID: '#Left_button',
                nextID: '#Right_button',
                onChange: function (index, total) {
                }
            });
        });
    </script>
</head>
<body>
    <section  data-role="gallery">
        <div id="album" class="pictures" data-role="pictures">
            <ul>
                <li><img src="./Image/49cBZ9Qzy1.png" alt="" /></li>
                <li><img src="./Image/TB1F4JxHXXXXXcgXXXXXK5zTVXX-520-280.png" alt="" /></li>
                <li><img src="./Image/TB1N13AGVXXXXapaXXXSutbFXXX.jpg" alt="" /></li>
                <li><img src="./Image/TB1st_5GVXXXXcRXXXXSutbFXXX.jpg" alt="" /></li>
                <li><img src="./Image/TB1W_dyHXXXXXbXXXXXSutbFXXX.jpg" alt="" /></li>
                <li><img src="./Image/TB157Q4GVXXXXbaXVXXSutbFXXX.jpg" alt="" /></li>
            </ul>
        </div>
    </section>
    <div id="buttons" data-role="galleryButtons"></div>
    <button id="Left_button">上一個</button>
    <button id="Right_button">下一個</button>
</body>
</html>


最終效果如下圖

示例圖片來自網絡版權歸其所有,本文只用於學習交流。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章