基于jquery的图片轮播 tab切换组件

  目前只添加了scroll和none的效果,scroll即滑动的效果,可以支持x和y方向的滑动;none就是没有任何效果,只是显示和隐藏,后续需要添加其他效果再做扩展,写的有点水,呵呵,在此留笔,防止丢失。

  Demo Address:http://demo.glzy8.com/js/2012/sinaapp/

  

复制代码 代码如下:

  /**

  * 巨无霸轮播

  */

  $.fn.loopSlider = function(option) {

  var setting = {

  // 默认显示的顺序

  initIndex: 1,

  // 加在title节点上的样式

  className: "current",

  // 轮播方向,默认为x轴方向轮播

  direct: "x",

  // 上一张按钮

  prevBtn: "",

  // 下一张按钮

  nextBtn: "",

  // 上下翻页按钮禁用的样式

  btnDisable: "disable",

  // 按钮按下的样式

  btnTouchClass: "",

  // 自动轮播

  auto: false,

  // 自动轮播时间间隔

  timeFlag: 4000,

  // 轮播效果时间

  scrollTime: 350,

  // 轮播效果

  effect: "scroll",

  // 在只有一个轮播元素的时候是否隐藏滑动按钮

  hideBtn: true,

  // 是否循环轮播

  cycle: true,

  // 轮播的内容区的容器路径

  contentContainer: "#imgScroll",

  // 轮播的内容区的节点

  contentChildTag: "li",

  // 标题轮播区域的容器路径

  titleContainer: "#titleScroll",

  // 标题轮播区域的节点

  titleChildTag: "li",

  // 轮播的内容区的数组

  cont: [],

  // 轮播的标题区的数组

  tabs: [],

  // 当前轮播序号

  current: 0,

  // 定时器

  ptr: "",

  // 轮播回调函数,每次轮播调用,参数为当前轮播的序号

  callback: function() {

  return true;

  }

  }

  if (option) {

  $.extend(setting, option);

  }

  // 初始化当前调用类型的函数

  setting.currentMethod = function() {

  return true;

  }

  var boss = $(this);

  // 如果不是第一个元素先轮播

  if (setting.initIndex != 1) {

  setting.current = setting.initIndex - 1;

  }

  // 获取轮播的节点列表

  var childList = boss.find(setting.contentContainer + " " + setting.contentChildTag);

  // 获取轮播标题节点列表

  var titleList = boss.find(setting.titleContainer + " " + setting.titleChildTag);

  // 保存内容区每一个轮播节点

  setting.cont = childList;

  // 保存标题的轮播节点

  setting.tabs = titleList;

  // 如果没有需要轮播的内容,直接返回

  if (setting.cont.length == 0) {

  return;

  }

  // 给内容区和标题区设置index属性

  childList.each(function(index) {

  $(this).attr("index", index);

  titleList.eq(index).attr("index", index);

  });

  // 上下箭头

  var nextBtn = boss.find(setting.nextBtn);

  var prevBtn = boss.find(setting.prevBtn);

  // 长度

  var counts = childList.length;

  // 轮播容器的父节点

  var childParent = childList.parent();

  var titleParent = titleList.parent();

  if (childList.length < setting.initIndex) {

  setting.current = 0;

  }

  // 初始化

  doInit();

  if (childList.length <= 1) {

  return;

  }

  /**

  * 处理无效果的切换

  */

  var doScrollNone = {

  process: function(i) {

  childList.eq(i).css("display", "block").siblings().css("display", "none");

  titleList.eq(i).addClass(setting.className).siblings().removeClass(setting.className);

  // 记录当前显示的节点

  setting.current = i;

  // 调用回调函数

  setting.callback(setting.current);

  },

  init: function() {

  setting.currentMethod = doScrollNone;

  bindEvent();

  // 自动轮播

  if (setting.auto) {

  processAuto();

  }

  // 初始化的时候也调用回调函数

  setting.callback(setting.current);

  }

  };

  var doScrollXY = {

  c_width: 0,

  c_height: 0,

  init: function() {

  // 轮播元素的宽度

  this.c_width = childList.width();

  // 轮播元素的高度

  this.c_height = childList.height();

  // x轴方向轮播

  if (setting.direct == "x") {

  childParent.width(this.c_width * (childList.length > 1 ? counts + 1 : counts));

  childParent.css("left", -this.c_width * (setting.current));

  } else {

  childParent.height(this.c_height * (childList.length > 1 ? counts + 1 : counts));

  childParent.css("top", -this.c_height * (setting.current));

  }

  titleList.eq(setting.current).addClass(setting.className).siblings().removeClass(setting.className);

  setting.currentMethod = doScrollXY;

  // 绑定事件

  bindEvent();

  // 初始化的时候也调用回调函数

  setting.callback(setting.current);

  // 自动轮播

  if (setting.auto) {

  processAuto();

  }

  },

  process: function(i, needFast) {

  setting.current = i;

  //alert(i)

  if (setting.direct == "x") {

  // 执行效果动画

  childParent.animate({

  left: "-" + (this.c_width * i)

  },

  (needFast ? 50 : setting.scrollTime),

  function() {

  if (setting.current == counts) {

  doScrollXY.processMove("left", $(this));

  }

  if (setting.auto) {

  processAuto();

  }

  });

  } else {

  childParent.animate({

  top: "-" + (this.c_height * i)

  },

  (needFast ? 50 : setting.scrollTime),

  function() {

  if (setting.current == counts) {

  doScrollXY.processMove("top", $(this));

  }

  if (setting.auto) {

  processAuto();

  }

  });

  }

  if (i == counts) {

  i = 0;

  }

  // 调用回调函数

  setting.callback(setting.current);

  titleList.eq(i).addClass(setting.className).siblings().removeClass(setting.className);

  },

  processMove: function(direct, node) {

  var childs = node.children();

  for (var i = 1; i < childs.length - 1; i++) {

  var removeNode = childs.eq(i).remove();

  node.append(removeNode);

  }

  var first = childs.eq(0).remove();

  node.append(first);

  node.css(direct, "0");

  }

  };

  switch (setting.effect) {

  case "none":

  doScrollNone.init();

  break;

  case "scroll":

  doScrollXY.init();

  break;

  }

  // 一些初始化操作

  function doInit() {

  childParent.css("position", "relative");

  if (!setting.cycle) {

  prevBtn.removeClass(setting.btnDisable);

  nextBtn.removeClass(setting.btnDisable);

  if (setting.current == 0) {

  prevBtn.addClass(setting.btnDisable);

  }

  if (setting.current == counts - 1) {

  nextBtn.addClass(setting.btnDisable);

  }

  }

  // 只有一个元素,并且需要隐藏按钮

  if (childList.length <= 1 && setting.hideBtn) {

  prevBtn.hide();

  nextBtn.hide();

  }

  // 克隆第一个元素到最后

  if (childList.length > 1) {

  var cloneNode = childList.eq(0).clone();

  cloneNode.attr("index", counts);

  cloneNode.appendTo(childParent);

  }

  }

  /**

  * 绑定轮播事件

  */

  function bindEvent() {

  nextBtn && nextBtn.bind("click",

  function(event) {

  // 如果按钮已经被禁用

  if ($(this).hasClass(setting.btnDisable)) {

  return;

  }

  var cur = setting.current;

  if (cur >= 0) {

  prevBtn.removeClass(setting.btnDisable);

  }

  if (cur == counts - 2 && !setting.cycle) {

  $(this).addClass(setting.btnDisable);

  }

  if (cur == counts) {

  setting.current = 1;

  } else if (cur == counts - 1) {

  // 轮播到最后一个

  setting.current = counts;

  } else {

  setting.current = cur + 1;

  }

  if (setting.ptr) {

  clearInterval(setting.ptr);

  setting.ptr = null;

  }

  $(this).addClass(setting.btnTouchClass);

  setting.currentMethod.process(setting.current);

  });

  prevBtn && prevBtn.bind("click",

  function() {

  if ($(this).hasClass(setting.btnDisable)) {

  return;

  }

  var cur = setting.current;

  if (cur <= counts - 1) {

  nextBtn.removeClass(setting.btnDisable);

  }

  if (cur == 1 && !setting.cycle) {

  $(this).addClass(setting.btnDisable);

  }

  setting.current = cur == 0 ? counts - 1 : cur - 1;

  if (setting.ptr) {

  clearInterval(setting.ptr);

  setting.ptr = null;

  }

  $(this).addClass(setting.btnTouchClass);

  var fast = false;

  if (cur == 0) {

  fast = true;

  }

  setting.currentMethod.process(setting.current, fast);

  });

  titleParent && titleParent.bind("click",

  function(e) {

  var element = $(e.target);

  // 得到轮播节点

  while (element[0].tagName != titleList[0].tagName) {

  element = element.parent();

  }

  if (setting.ptr) {

  clearInterval(setting.ptr);

  setting.ptr = null;

  }

  var index = parseInt(element.attr("index"), 10);

  if (index != 0) {

  prevBtn.removeClass(setting.btnDisable);

  } else if (!setting.cycle) {

  prevBtn.addClass(setting.btnDisable);

  }

  if (index != counts - 1) {

  nextBtn.removeClass(setting.btnDisable);

  } else if (!setting.cycle) {

  nextBtn.addClass(setting.btnDisable);

  }

  setting.currentMethod.process(index);

  });

  childParent[0].ontouchstart = handleTouchStart;

  // 触摸屏幕事件

  function handleTouchStart(event) {

  var element = $(event.target);

  // 得到标题节点

  while (element[0].tagName != childList[0].tagName) {

  element = element.parent();

  }

  if (event.targetTouches.length == 0) {

  return;

  }

  var touch = event.targetTouches[0];

  var startX = touch.pageX;

  var startY = touch.pageY;

  var moveDirect = "";

  var currentPosition = setting.direct == "x" ? childParent.css("left") : childParent.css("top");

  if (setting.ptr) {

  clearInterval(setting.ptr);

  setting.ptr = null;

  }

  // 手指滑动事件

  childParent[0].ontouchmove = handleTouchMove;

  function handleTouchMove(moveEvent) {

  var movetouch = moveEvent.targetTouches[0];

  if (setting.direct == 'x') {

  var moveX = movetouch.pageX;

  var moveY = movetouch.pageY;

  var x = moveX - startX;

  var y = moveY - startY;

  // 这里的目的是在左右滑动图片的时候,阻止浏览器的默认事件,但是如果是上下滑动的情况,一般是滑动滚动条,不能直接就阻止浏览器默认事件,不然会导致用户在上下滑动的时候页面停止的情况,这里设置的是在x轴方向要比在Y轴方向滑动至少多10的像素,可以有效的避免上述情况发生

  if (Math.abs(x) - Math.abs(y) > 10) {

  // 阻止默认的事件

  moveEvent.preventDefault();

  childParent.css("left", parseFloat(currentPosition) + x);

  moveDirect = x > 0 ? "sub": "add";

  } else {

  return;

  }

  } else {

  // Y轴方向滚动

  moveEvent.preventDefault();

  var moveY = touch.pageY;

  var y = moveY - startY;

  childParent.css("top", parseFloat(currentPosition) + y);

  moveDirect = y > 0 ? "sub": "add";

  }

  childParent[0].ontouchend = handleTouchEnd;

  }

  //手指离开屏幕

  function handleTouchEnd() {

  //根据手指移动的方向,判断下一个要显示的节点序号

  var fast = false;

  if (moveDirect == "add") {

  if (setting.current == counts) {

  setting.current = 1;

  } else {

  setting.current = setting.current + 1;

  }

  } else {

  if (setting.current == 0) {

  setting.current = counts - 1;

  fast = true;

  } else {

  setting.current = setting.current - 1;

  }

  }

  // 调用对应的处理函数

  setting.currentMethod.process(setting.current, fast);

  childParent[0].ontouchend = null;

  childParent[0].ontouchmove = null;

  }

  }

  }

  /**

  * 自动轮播

  */

  function processAuto() {

  if (setting.ptr) {

  clearInterval(setting.ptr);

  setting.ptr = null;

  }

  // 设置轮播定时器

  setting.ptr = setInterval(function() {

  if (setting.current == counts) {

  setting.current = 1;

  } else if (setting.current == counts - 1) {

  // 轮播到最后一个

  setting.current = counts;

  } else {

  setting.current = setting.current + 1;

  }

  var index = setting.current;

  if (index != 0) {

  prevBtn.removeClass(setting.btnDisable);

  } else if (!setting.cycle) {

  prevBtn.addClass(setting.btnDisable);

  }

  if (index != counts - 1) {

  nextBtn.removeClass(setting.btnDisable);

  } else if (!setting.cycle) {

  nextBtn.addClass(setting.btnDisable);

  }

  setting.currentMethod.process(setting.current);

  },

  setting.timeFlag);

  }

  // 返回一个函数,可以在调用返回函数,指定下一次需要轮播的图片的序号,一般用在点击一个小图,然后需要查看大图的情况下,那么就只需要给大图绑定一次轮播事件,再点击某一张小图的时候只需要调用该函数,把对应的序号传入即可

  return function(index) {

  if (index < 0) {

  index = 0;

  } else if (index >= counts) {

  index = counts - 1;

  }

  setting.currentMethod.process(index);

  }

  }