以下是 移动端左右+自动滚动jQuery插件轮播切换特效代码 的示例演示效果:
部分效果截图:
HTML代码(index.html):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="target-densitydpi=device-dpi,width=device-width,initial-scale=1.0,minimum-scale=0.1,maximum-scale=1,user-scalable=no" />
<meta http-equiv="X-UA-Compatible" content="IE=7" />
<title>移动端左右+自动滚动jQuery插件</title>
<link href="css/layout.css" type="text/css" rel="stylesheet" />
</head>
<body>
<div>
<article>
<!--scroll-->
<div class="scroll relative">
<div class="scroll_box" id="scroll_img">
<ul class="scroll_wrap">
<li><a href="#"><img src="images/1.jpg" width="100%" /></a></li>
<li><a href="#"><img src="images/2.jpg" width="100%" /></a></li>
<li><a href="#"><img src="images/3.jpg" width="100%" /></a></li>
</ul>
</div>
<span class="scroll_position_bg opacity6"></span>
<ul class="scroll_position" id='scroll_position'>
<li class="on"><a href="javascript:void(0);">1</a></li>
<li><a href="javascript:void(0);">2</a></li>
<li><a href="javascript:void(0);">3</a></li>
</ul>
</div>
<!--scroll-->
</article>
</div>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src='js/hhSwipe.js'></script>
<script>
var slider = Swipe(document.getElementById('scroll_img'), {
auto: 3000,
continuous: true,
callback: function(pos) {
var i = bullets.length;
while (i--) {
bullets[i].className = ' ';
}
bullets[pos].className = 'on';
}
});
var bullets = document.getElementById('scroll_position').getElementsByTagName('li');
$(function(){
$('.scroll_position_bg').css({
width:$('#scroll_position').width()
});
});
</script>
</body>
</html>
JS代码(hhSwipe.js):
function Swipe(container,options){
"use strict";
// utilities var noop = function(){
}
;
// simple no operation function var offloadFn = function(fn){
setTimeout(fn || noop,0)}
;
// offload a functions execution // check browser capabilities var browser ={
addEventListener:!!window.addEventListener,touch:('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch,transitions:(function(temp){
var props = ['transitionProperty','WebkitTransition','MozTransition','OTransition','msTransition'];
for ( var i in props ) if (temp.style[ props[i] ] !== undefined) return true;
return false;
}
)(document.createElement('swipe'))}
;
// quit if no root element if (!container) return;
var element = container.children[0];
var slides,slidePos,width,length;
options = options ||{
}
;
var index = parseInt(options.startSlide,10) || 0;
var speed = options.speed || 300;
options.continuous = options.continuous !== undefined ? options.continuous:true;
function setup(){
// cache slides slides = element.children;
length = slides.length;
// set continuous to false if only one slide if (slides.length < 2) options.continuous = false;
//special case if two slides if (browser.transitions && options.continuous && slides.length < 3){
element.appendChild(slides[0].cloneNode(true));
element.appendChild(element.children[1].cloneNode(true));
slides = element.children;
}
// create an array to store current positions of each slide slidePos = new Array(slides.length);
// determine width of each slide width = container.getBoundingClientRect().width || container.offsetWidth;
element.style.width = (slides.length * width) + 'px';
// stack elements var pos = slides.length;
while(pos--){
var slide = slides[pos];
slide.style.width = width + 'px';
slide.setAttribute('data-index',pos);
if (browser.transitions){
slide.style.left = (pos * -width) + 'px';
move(pos,index > pos ? -width:(index < pos ? width:0),0);
}
}
// reposition elements before and after index if (options.continuous && browser.transitions){
move(circle(index-1),-width,0);
move(circle(index+1),width,0);
}
if (!browser.transitions) element.style.left = (index * -width) + 'px';
container.style.visibility = 'visible';
}
function prev(){
if (options.continuous) slide(index-1);
else if (index) slide(index-1);
}
function next(){
if (options.continuous) slide(index+1);
else if (index < slides.length - 1) slide(index+1);
}
function circle(index){
// a simple positive modulo using slides.length return (slides.length + (index % slides.length)) % slides.length;
}
function slide(to,slideSpeed){
// do nothing if already on requested slide if (index == to) return;
if (browser.transitions){
var direction = Math.abs(index-to) / (index-to);
// 1:backward,-1:forward // get the actual position of the slide if (options.continuous){
var natural_direction = direction;
direction = -slidePos[circle(to)] / width;
// if going forward but to < index,use to = slides.length + to // if going backward but to > index,use to = -slides.length + to if (direction !== natural_direction) to = -direction * slides.length + to;
}
var diff = Math.abs(index-to) - 1;
// move all the slides between index and to in the right direction while (diff--) move( circle((to > index ? to:index) - diff - 1),width * direction,0);
to = circle(to);
move(index,width * direction,slideSpeed || speed);
move(to,0,slideSpeed || speed);
if (options.continuous) move(circle(to - direction),-(width * direction),0);
// we need to get the next in place}
else{
to = circle(to);
animate(index * -width,to * -width,slideSpeed || speed);
//no fallback for a circular continuous if the browser does not accept transitions}
index = to;
offloadFn(options.callback && options.callback(index,slides[index]));
}
function move(index,dist,speed){
translate(index,dist,speed);
slidePos[index] = dist;
}
function translate(index,dist,speed){
var slide = slides[index];
var style = slide && slide.style;
if (!style) return;
style.webkitTransitionDuration = style.MozTransitionDuration = style.msTransitionDuration = style.OTransitionDuration = style.transitionDuration = speed + 'ms';
style.webkitTransform = 'translate(' + dist + 'px,0)' + 'translateZ(0)';
style.msTransform = style.MozTransform = style.OTransform = 'translateX(' + dist + 'px)';
}
function animate(from,to,speed){
// if not an animation,just reposition if (!speed){
element.style.left = to + 'px';
return;
}
var start = +new Date;
var timer = setInterval(function(){
var timeElap = +new Date - start;
if (timeElap > speed){
element.style.left = to + 'px';
if (delay) begin();
options.transitionEnd && options.transitionEnd.call(event,index,slides[index]);
clearInterval(timer);
return;
}
element.style.left = (( (to - from) * (Math.floor((timeElap / speed) * 100) / 100) ) + from) + 'px';
}
,4);
}
// setup auto slideshow var delay = options.auto || 0;
var interval;
function begin(){
interval = setTimeout(next,delay);
}
function stop(){
delay = 0;
clearTimeout(interval);
}
// setup initial vars var start ={
}
;
var delta ={
}
;
var isScrolling;
// setup event capturing var events ={
handleEvent:function(event){
switch (event.type){
case 'touchstart':this.start(event);
break;
case 'touchmove':this.move(event);
break;
case 'touchend':offloadFn(this.end(event));
break;
case 'webkitTransitionEnd':case 'msTransitionEnd':case 'oTransitionEnd':case 'otransitionend':case 'transitionend':offloadFn(this.transitionEnd(event));
break;
case 'resize':offloadFn(setup.call());
break;
}
if (options.stopPropagation) event.stopPropagation();
}
,start:function(event){
var touches = event.touches[0];
// measure start values start ={
// get initial touch coords x:touches.pageX,y:touches.pageY,// store time to determine touch duration time:+new Date}
;
// used for testing first move event isScrolling = undefined;
// reset delta and end measurements delta ={
}
;
// attach touchmove and touchend listeners element.addEventListener('touchmove',this,false);
element.addEventListener('touchend',this,false);
}
,move:function(event){
// ensure swiping with one touch and not pinching if ( event.touches.length > 1 || event.scale && event.scale !== 1) return if (options.disableScroll) event.preventDefault();
var touches = event.touches[0];
// measure change in x and y delta ={
x:touches.pageX - start.x,y:touches.pageY - start.y}
// determine if scrolling test has run - one time test if ( typeof isScrolling == 'undefined'){
isScrolling = !!( isScrolling || Math.abs(delta.x) < Math.abs(delta.y) );
}
// if user is not trying to scroll vertically if (!isScrolling){
// prevent native scrolling event.preventDefault();
// stop slideshow stop();
// increase resistance if first or last slide if (options.continuous){
// we don't add resistance at the end translate(circle(index-1),delta.x + slidePos[circle(index-1)],0);
translate(index,delta.x + slidePos[index],0);
translate(circle(index+1),delta.x + slidePos[circle(index+1)],0);
}
else{
delta.x = delta.x / ( (!index && delta.x > 0 // if first slide and sliding left || index == slides.length - 1 // or if last slide and sliding right && delta.x < 0 // and if sliding at all ) ? ( Math.abs(delta.x) / width + 1 ) // determine resistance level:1 );
// no resistance if false // translate 1:1 translate(index-1,delta.x + slidePos[index-1],0);
translate(index,delta.x + slidePos[index],0);
translate(index+1,delta.x + slidePos[index+1],0);
}
}
}
,end:function(event){
// measure duration var duration = +new Date - start.time;
// determine if slide attempt triggers next/prev slide var isValidSlide = Number(duration) < 250 // if slide duration is less than 250ms && Math.abs(delta.x) > 20 // and if slide amt is greater than 20px || Math.abs(delta.x) > width/2;
// or if slide amt is greater than half the width // determine if slide attempt is past start and end var isPastBounds = !index && delta.x > 0 // if first slide and slide amt is greater than 0 || index == slides.length - 1 && delta.x < 0;
// or if last slide and slide amt is less than 0 if (options.continuous) isPastBounds = false;
// determine direction of swipe (true:right,false:left) var direction = delta.x < 0;
// if not scrolling vertically if (!isScrolling){
if (isValidSlide && !isPastBounds){
if (direction){
if (options.continuous){
// we need to get the next in this direction in place move(circle(index-1),-width,0);
move(circle(index+2),width,0);
}
else{
move(index-1,-width,0);
}
move(index,slidePos[index]-width,speed);
move(circle(index+1),slidePos[circle(index+1)]-width,speed);
index = circle(index+1);
}
else{
if (options.continuous){
// we need to get the next in this direction in place move(circle(index+1),width,0);
move(circle(index-2),-width,0);
}
else{
move(index+1,width,0);
}
move(index,slidePos[index]+width,speed);
move(circle(index-1),slidePos[circle(index-1)]+width,speed);
index = circle(index-1);
}
options.callback && options.callback(index,slides[index]);
}
else{
if (options.continuous){
move(circle(index-1),-width,speed);
move(index,0,speed);
move(circle(index+1),width,speed);
}
else{
move(index-1,-width,speed);
move(index,0,speed);
move(index+1,width,speed);
}
}
}
// kill touchmove and touchend event listeners until touchstart called again element.removeEventListener('touchmove',events,false) element.removeEventListener('touchend',events,false)}
,transitionEnd:function(event){
if (parseInt(event.target.getAttribute('data-index'),10) == index){
if (delay) begin();
options.transitionEnd && options.transitionEnd.call(event,index,slides[index]);
}
}
}
// trigger setup setup();
// start auto slideshow if applicable if (delay) begin();
// add event listeners if (browser.addEventListener){
// set touchstart event on element if (browser.touch) element.addEventListener('touchstart',events,false);
if (browser.transitions){
element.addEventListener('webkitTransitionEnd',events,false);
element.addEventListener('msTransitionEnd',events,false);
element.addEventListener('oTransitionEnd',events,false);
element.addEventListener('otransitionend',events,false);
element.addEventListener('transitionend',events,false);
}
// set resize event on window window.addEventListener('resize',events,false);
}
else{
window.onresize = function (){
setup()}
;
// to play nice with old IE}
// expose the Swipe API return{
setup:function(){
setup();
}
,slide:function(to,speed){
// cancel slideshow stop();
slide(to,speed);
}
,prev:function(){
// cancel slideshow stop();
prev();
}
,next:function(){
// cancel slideshow stop();
next();
}
,getPos:function(){
// return current index position return index;
}
,getNumSlides:function(){
// return total number of slides return length;
}
,kill:function(){
// cancel slideshow stop();
// reset element element.style.width = 'auto';
element.style.left = 0;
// reset slides var pos = slides.length;
while(pos--){
var slide = slides[pos];
slide.style.width = '100%';
slide.style.left = 0;
if (browser.transitions) translate(pos,0,0);
}
// removed event listeners if (browser.addEventListener){
// remove current event listeners element.removeEventListener('touchstart',events,false);
element.removeEventListener('webkitTransitionEnd',events,false);
element.removeEventListener('msTransitionEnd',events,false);
element.removeEventListener('oTransitionEnd',events,false);
element.removeEventListener('otransitionend',events,false);
element.removeEventListener('transitionend',events,false);
window.removeEventListener('resize',events,false);
}
else{
window.onresize = null;
}
}
}
}
if ( window.jQuery || window.Zepto ){
(function($){
$.fn.Swipe = function(params){
return this.each(function(){
$(this).data('Swipe',new Swipe($(this)[0],params));
}
);
}
}
)( window.jQuery || window.Zepto )}
CSS代码(layout.css):
@charset "utf-8";/*** User:huanhuan* QQ:651471385* Email:th.wanghuan@gmail.com* 微博:huanhuan的天使* Data 2013-12-04* Dependence jquery-1.7.2.min.js* web:https://github.com/huanhuan1989http://www.cnblogs.com/huanhuan1989/* Copyright:2005-2013 www.techholder.com Inc. All rights reserved.*/
/*Initialization style*/
body{color:#000;background:url(../img/paper.jpg) repeat #fff;font:normal 100% Arial,sans-serif,Microsoft Yahei;margin:0;padding:0;}
html,body,form,input,select,textarea,div,p,h1,h2,h3,h4,h5,h6,p,ul,ol,li,form,img,dl,dt,dd,table,th,td,blockquote,fieldset,div,strong,label,em{margin:0;padding:0;}
ul,li,dl,dt,dd{list-style:none;}
h1,h2,h3{font-weight:bold;color:#303030;font-family:Microsoft Yahei,w3;}
table,td,img{border:0;}
table,tr,td{border-collapse:collapse;border-spacing:0;}
a:link,a:visited{color:#0fa7ff;text-decoration:none;outline:none;cursor:pointer;}
a:hover{color:#ff6407;text-decoration:underline;}
button{cursor:pointer;}
/*public*/
.left{float:left;}
.right{float:right;}
.relative{position:relative;left:0;top:0;}
.clearfix:before,.clearfix:after{content:"";display:table;}
.clearfix:after{clear:both;}
.clearfix{zoom:1;}
.opacity6{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";/* ie8 */
filter:alpha(opacity=60);/* ie5-7 */
opacity:0.6;/* css standard,currently it works in most modern browsers */
}
.app_center{width:100%;min-width:320px;margin-left:auto;margin-right:auto;}
.red{color:red;}
.c_999{color:#999;}
.pt10{padding-top:10px;}
.hide{display:none;}
/*public scroll*/
.scroll{margin:120px auto;max-width:560px;}
.scroll_box{overflow:hidden;visibility:hidden;position:relative;}
.scroll_wrap{overflow:hidden;position:relative;}
.scroll_wrap li{position:relative;display:block;width:100%;float:left;}
.scroll_wrap li a{display:block;margin:0 auto;position:relative;}
.scroll_position{position:absolute;left:45%;z-index:400px;bottom:14px;}
.scroll_position li{display:inline-block;width:16px;height:16px;border-radius:10px;background:#fff;}
.scroll_position li a{font-size:0;}
.scroll_position li.on{background-color:#ffd800;}
.scroll_position_bg{background:#000;position:absolute;bottom:12px;left:42%;padding:0 15px;z-index:380px;height:26px;border-radius:26px;}