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>
最終效果如下圖
示例圖片來自網絡版權歸其所有,本文只用於學習交流。