1、设计目标:设计一个可以支持触屏左右滑动的循环相册。
2、设计思路:将图片横向排放到一个框中。关键问题出在循环设计上。
因为当相册播放到第一张时,点上一张按钮或向右滑动这时应该播放相册的最后一张,并且要保持视觉上的连续性。
同里在相册最后一张向左滑动或点下一张按钮也有同样的问题。
3、如何解决循环?
办法如下图
红框代表相册,数字1代表的是第一张图片,数字n代表的是最后一张图片。
当从第二张图片的1向右滑动至第一张图片1时立即跳转到倒数第二张图片的n。
同理当从倒数第二张图片的n向左滑动至最后一张图片1时,立即跳转到第二张图片的1。
插件代码实现如下。
/*
* jQuery Mobile Framework : "gallery" plugin
*
* author: codec007
* date : 20150106
* email : mailzy@vip.qq.com
*
* 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>
最终效果如下图
示例图片来自网络版权归其所有,本文只用于学习交流。