使用jQuery制作基础的Web图片轮播效果


Posted in Javascript onApril 22, 2016

首先看一下效果:

使用jQuery制作基础的Web图片轮播效果

就这么个意思,没截动图哈~

轮播效果分析:
轮播效果大致可以分为3个部分:轮播图片(图片或者是包含容器),控制轮播图显示的按钮(向左、向右按钮,索引按钮(例如上面效果图的顶部的数字按钮)),每隔一段时间轮流显示轮播图片。
轮播图的显示:要显示的轮播图显示,不需要显示的轮播图隐藏;通常将这些轮播图片以定位的方式重叠在一起,每次显示一张轮播图片。
控制按钮:鼠标点击或者移到索引按钮上面时,显示对应索引位置的轮播图;向上、向下按钮负责控制显示上一张、下一张轮播图片。
其它:一般索引按钮有激活状态和未激活状态共2种状态;鼠标移到轮播图片上面时应该停止自动轮播,鼠标离开时开始自动轮播。

轮播效果实现笔记:
jquery提供了丰富的选择器以及用来挑选元素的方法,这极大的简化了我们的开发,例如$(".slider-item").filter(".slider-item-selected")选择了当前处于激活状态的索引按钮。
两张轮播图的切换显示效果是通过jquery的fadeOut()和fadeIn()方法来实现的,具体的使用参照jquery的api;
CSS透明背景的实现:  background: rgba(0, 0, 0, 0.2);filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#33000000,endColorstr=#33000000); (可以参看下面的参看资料),兼容大部分主流浏览器包括IE;为什么不使用opacity呢?因为opacity会使文字也透明(子元素也会透明)。
HTML骨架很重要,你写的html的结果应该是良好的。

代码部分:

HTML:

<pre name="code" class="html"><div class="slider">

 <div class="slider-extra">
 <ul class="slider-nav">
  <li class="slider-item">1</li>
  <li class="slider-item">2</li>
  <li class="slider-item">3</li>
  <li class="slider-item">4</li>
 </ul>
 <div class="slider-page">
  <a class="slider-pre" href="javascript:;;"><</a>
  <a class="slider-next" href="javascript:;;">></a>
 </div>
 </div>
</div>

CSS:

* {
 padding: 0px;
 margin: 0px;
}
a {
 text-decoration: none;
}
ul {
 list-style: outside none none;
}
.slider, .slider-panel img, .slider-extra {
 width: 650px;
 height: 413px;
}
.slider {
 text-align: center;
 margin: 30px auto;
 position: relative;
}
.slider-panel, .slider-nav, .slider-pre, .slider-next {
 position: absolute;
 z-index: 8;
}
.slider-panel {
 position: absolute;
}
.slider-panel img {
 border: none;
}
.slider-extra {
 position: relative;
}
.slider-nav {
 margin-left: -51px;
 position: absolute;
 left: 50%;
 bottom: 4px;
}
.slider-nav li {
 background: #3e3e3e;
 border-radius: 50%;
 color: #fff;
 cursor: pointer;
 margin: 0 2px;
 overflow: hidden;
 text-align: center;
 display: inline-block;
 height: 18px;
 line-height: 18px;
 width: 18px;
}
.slider-nav .slider-item-selected {
 background: blue;
}
.slider-page a{
 background: rgba(0, 0, 0, 0.2);
 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#33000000,endColorstr=#33000000);
 color: #fff;
 text-align: center;
 display: block;
 font-family: "simsun";
 font-size: 22px;
 width: 28px;
 height: 62px;
 line-height: 62px;
 margin-top: -31px;
 position: absolute;
 top: 50%;
}
.slider-page a:HOVER {
 background: rgba(0, 0, 0, 0.4);
 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#66000000,endColorstr=#66000000);
}
.slider-next {
 left: 100%;
 margin-left: -28px;
}

JavaScript:

$(document).ready(function() {
 var length,
 currentIndex = 0,
 interval,
 hasStarted = false, //是否已经开始轮播
 t = 3000; //轮播时间间隔
 length = $('.slider-panel').length;
 
 //将除了第一张图片隐藏
 $('.slider-panel:not(:first)').hide();
 //将第一个slider-item设为激活状态
 $('.slider-item:first').addClass('slider-item-selected');
 //隐藏向前、向后翻按钮
 $('.slider-page').hide();
 
 //鼠标上悬时显示向前、向后翻按钮,停止滑动,鼠标离开时隐藏向前、向后翻按钮,开始滑动
 $('.slider-panel, .slider-pre, .slider-next').hover(function() {
 stop();
 $('.slider-page').show();
 }, function() {
 $('.slider-page').hide();
 start();
 });
 
 $('.slider-item').hover(function(e) {
 stop();
 var preIndex = $(".slider-item").filter(".slider-item-selected").index();
 currentIndex = $(this).index();
 play(preIndex, currentIndex);
 }, function() {
 start();
 });
 
 $('.slider-pre').unbind('click');
 $('.slider-pre').bind('click', function() {
 pre();
 });
 $('.slider-next').unbind('click');
 $('.slider-next').bind('click', function() {
 next();
 });
 
 /**
 * 向前翻页
 */
 function pre() {
 var preIndex = currentIndex;
 currentIndex = (--currentIndex + length) % length;
 play(preIndex, currentIndex);
 }
 /**
 * 向后翻页
 */
 function next() {
 var preIndex = currentIndex;
 currentIndex = ++currentIndex % length;
 play(preIndex, currentIndex);
 }
 /**
 * 从preIndex页翻到currentIndex页
 * preIndex 整数,翻页的起始页
 * currentIndex 整数,翻到的那页
 */
 function play(preIndex, currentIndex) {
 $('.slider-panel').eq(preIndex).fadeOut(500)
  .parent().children().eq(currentIndex).fadeIn(1000);
 $('.slider-item').removeClass('slider-item-selected');
 $('.slider-item').eq(currentIndex).addClass('slider-item-selected');
 }
 
 /**
 * 开始轮播
 */
 function start() {
 if(!hasStarted) {
  hasStarted = true;
  interval = setInterval(next, t);
 }
 }
 /**
 * 停止轮播
 */
 function stop() {
 clearInterval(interval);
 hasStarted = false;
 }
 
 //开始轮播
 start();
});

首先是初始化部分:将除了第一张轮播图片意外的图片都隐藏,并且隐藏向前、向后按钮,使第一个索引按钮处于激活状态。
事件部分:通过jquery的hover()绑定鼠标上悬以及离开时的事件处理, jquery的bind()方法绑定鼠标点击事件处理向前、向后翻动、
轮播控制:pre(), next(), play(), start()开始自动轮播,stop()停止自动轮播。
上面的js写的比较散,结构也不太好,读起来也比较费力,也不易使用,耦合度较高。下篇将给出一个纯粹的jquery轮播插件, 该插件可以定制各种效果,方便的配置以及可扩展。

下面是整体的代码:
index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jquery轮播效果图 - by RiccioZhang</title>
<script type="text/javascript" src="scripts/jquery-1.9.1.js"></script>
<style type="text/css">
 * {
 padding: 0px;
 margin: 0px;
 }
 a {
 text-decoration: none;
 }
 ul {
 list-style: outside none none;
 }
 .slider, .slider-panel img, .slider-extra {
 width: 650px;
 height: 413px;
 }
 .slider {
 text-align: center;
 margin: 30px auto;
 position: relative;
 }
 .slider-panel, .slider-nav, .slider-pre, .slider-next {
 position: absolute;
 z-index: 8;
 }
 .slider-panel {
 position: absolute;
 }
 .slider-panel img {
 border: none;
 }
 .slider-extra {
 position: relative;
 }
 .slider-nav {
 margin-left: -51px;
 position: absolute;
 left: 50%;
 bottom: 4px;
 }
 .slider-nav li {
 background: #3e3e3e;
 border-radius: 50%;
 color: #fff;
 cursor: pointer;
 margin: 0 2px;
 overflow: hidden;
 text-align: center;
 display: inline-block;
 height: 18px;
 line-height: 18px;
 width: 18px;
 }
 .slider-nav .slider-item-selected {
 background: blue;
 }
 .slider-page a{
 background: rgba(0, 0, 0, 0.2);
 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#33000000,endColorstr=#33000000);
 color: #fff;
 text-align: center;
 display: block;
 font-family: "simsun";
 font-size: 22px;
 width: 28px;
 height: 62px;
 line-height: 62px;
 margin-top: -31px;
 position: absolute;
 top: 50%;
 }
 .slider-page a:HOVER {
 background: rgba(0, 0, 0, 0.4);
 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#66000000,endColorstr=#66000000);
 }
 .slider-next {
 left: 100%;
 margin-left: -28px;
 }
</style>
<script type="text/javascript">
 $(document).ready(function() {
 var length,
  currentIndex = 0,
  interval,
  hasStarted = false, //是否已经开始轮播
  t = 3000; //轮播时间间隔
 length = $('.slider-panel').length;
 
 //将除了第一张图片隐藏
 $('.slider-panel:not(:first)').hide();
 //将第一个slider-item设为激活状态
 $('.slider-item:first').addClass('slider-item-selected');
 //隐藏向前、向后翻按钮
 $('.slider-page').hide();
 
 //鼠标上悬时显示向前、向后翻按钮,停止滑动,鼠标离开时隐藏向前、向后翻按钮,开始滑动
 $('.slider-panel, .slider-pre, .slider-next').hover(function() {
  stop();
  $('.slider-page').show();
 }, function() {
  $('.slider-page').hide();
  start();
 });
 
 $('.slider-item').hover(function(e) {
  stop();
  var preIndex = $(".slider-item").filter(".slider-item-selected").index();
  currentIndex = $(this).index();
  play(preIndex, currentIndex);
 }, function() {
  start();
 });
 
 $('.slider-pre').unbind('click');
 $('.slider-pre').bind('click', function() {
  pre();
 });
 $('.slider-next').unbind('click');
 $('.slider-next').bind('click', function() {
  next();
 });
 
 /**
  * 向前翻页
  */
 function pre() {
  var preIndex = currentIndex;
  currentIndex = (--currentIndex + length) % length;
  play(preIndex, currentIndex);
 }
 /**
  * 向后翻页
  */
 function next() {
  var preIndex = currentIndex;
  currentIndex = ++currentIndex % length;
  play(preIndex, currentIndex);
 }
 /**
  * 从preIndex页翻到currentIndex页
  * preIndex 整数,翻页的起始页
  * currentIndex 整数,翻到的那页
  */
 function play(preIndex, currentIndex) {
  $('.slider-panel').eq(preIndex).fadeOut(500)
  .parent().children().eq(currentIndex).fadeIn(1000);
  $('.slider-item').removeClass('slider-item-selected');
  $('.slider-item').eq(currentIndex).addClass('slider-item-selected');
 }
 
 /**
  * 开始轮播
  */
 function start() {
  if(!hasStarted) {
  hasStarted = true;
  interval = setInterval(next, t);
  }
 }
 /**
  * 停止轮播
  */
 function stop() {
  clearInterval(interval);
  hasStarted = false;
 }
 
 //开始轮播
 start();
 });
</script>
</head>
<body>
 <div class="slider">
 <div class="slider-extra">
  <ul class="slider-nav">
  <li class="slider-item">1</li>
  <li class="slider-item">2</li>
  <li class="slider-item">3</li>
  <li class="slider-item">4</li>
  </ul>
  <div class="slider-page">
  <a class="slider-pre" href="javascript:;;"><</a>
  <a class="slider-next" href="javascript:;;">></a>
  </div>
 </div>
 </div>
</body>
</html>

至此一个简单的jquery轮播效果就完成了,当然还有很多需要改进的地方。

使用插件实现
上面的效果看起来还令人满意,唯一不足的就是:每次需要轮播效果时,要将代码复制粘贴过去,如果有些部分需要修改(例如:轮播时的动画效果,前一篇使用的是jquery的淡入淡出效果,如果改成滑动效果,不可避免的要修改js代码),那么就需要对js代码进行修改,对我所写的jquery轮播效果的js代码不熟悉的程序员来说,修改这些js确实很困难。轮播插件所要实现的目标之一就是插件可以灵活配置(不光只是本篇文章的插件),程序员只需要写少量的代码就可以实现丰富的功能,这当然是一件很好的事情。本篇文章的轮播插件的html和css部分需要程序员自己编写,而实现效果的js只需要少量的编写。
这里我们使用到的zslider插件在GitHub上开源:
github:https://github.com/ricciozhang/zslider_v1
嗯,我们来看代码:

(function($, window, document) { 
  //---- Statics 
  var DEFAULT_ANIMATE_TYPE = 'fade',  
    ARRAY_SLICE = [].slice, 
    ARRAY_CONCAT = [].concat 
    ; 
   
  //---- Methods 
  function concatArray() { 
    var deep = false, 
      result = []; 
    if(arguments.length > 0 &&  
        arguments[arguments.length - 1] === true) { 
      deep = true; 
    } 
    for(var i = 0; i < arguments.length; i++) { 
      if(!!arguments[i].length) { 
        if(deep) { 
          for(var j = 0; j < arguments[i].length; j++) { 
            //recursive call 
            result = ARRAY_CONCAT.call(result,  
                concatArray(arguments[i][j], true)); 
          } 
        } else { 
          result = ARRAY_CONCAT.call(result, arguments[i]); 
        } 
      } else if(i != arguments.length - 1 ||  
          (arguments[arguments.length - 1] !== true && 
              arguments[arguments.length - 1] !== false)) { 
        result.push(arguments[i]); 
      } 
    } 
    return result; 
  } 
 
  //----- Core 
  $.fn.extend({ 
    zslider: function(zsliderSetting, autoStart) { 
      var itemLenght = 0, 
        currItemIndex = 0, 
        started = false, 
        oInterval = {}, 
        setting = { 
          intervalTime: 3000, 
          step: 1, 
          imagePanels: $(), 
          animateConfig: { 
            atype: 'fade', 
            fadeInSpeed: 500, 
            fadeOutSpeed: 1000 
          }, 
          panelHoverStop: true, 
          ctrlItems: $(), 
          ctrlItemActivateType: 'hover' || 'click', 
          ctrlItemHoverCls: '', 
          flipBtn: {}, 
          panelHoverShowFlipBtn: true, 
          callbacks: { 
            animate: null 
          } 
        }, 
        that = this 
        ; 
       
      //core methods 
      var slider = { 
          pre: function() { 
            var toIndex = itemLenght +  
              (currItemIndex - setting.step) % itemLenght; 
            slider.to(toIndex); 
          }, 
          next: function() { 
            var toIndex = (currItemIndex + setting.step) % itemLenght; 
            slider.to(toIndex); 
          }, 
          to: function(toIndex) { 
            //handle the index value 
            if(typeof toIndex === 'function') { 
              toIndex = toIndex.call(that, concatArray(setting.imagePanels, true),  
                    concatArray(setting.ctrlItems, true), 
                      currItemIndex, step); 
            } 
            if(window.isNaN(toIndex)) { 
              toIndex = 0; 
            } 
            toIndex = Math.round(+toIndex) % itemLenght; 
            if(toIndex < 0) { 
              toIndex = itemLenght + toIndex; 
            } 
             
            var currentPanel = setting.imagePanels.eq(currItemIndex), 
            toPanel = setting.imagePanels.eq(toIndex), 
            currrntCtrlItem = setting.ctrlItems.eq(currItemIndex) 
            toCtrlItem = setting.ctrlItems.eq(toIndex) 
            ; 
            if(!setting.callbacks.animate ||  
                setting.callbacks.animate.call(that,  
                    concatArray(setting.imagePanels, true),  
                      concatArray(setting.ctrlItems, true), 
                        currItemIndex, toIndex) === true) { 
              currrntCtrlItem.removeClass(setting.ctrlItemHoverCls); 
              toCtrlItem.addClass(setting.ctrlItemHoverCls); 
               
              toPanel.fadeIn(setting.animateConfig.fadeInSpeed); 
              currentPanel.fadeOut(setting.animateConfig.fadeOutSpeed); 
            } 
             
            //set the current item index 
            currItemIndex = toIndex; 
          }, 
          start: function() { 
            if(!started) { 
              started = true; 
              oInterval =  
                window.setInterval(slider.next, setting.intervalTime); 
            } 
          }, 
          stop: function() { 
            if(started) { 
              started = false; 
              window.clearInterval(oInterval); 
            } 
          }, 
          isStarted: function() { 
            return started; 
          } 
      }; 
      function initData() { 
        if(zsliderSetting) { 
          var temp_callbacks = zsliderSetting.callbacks; 
           
          $.extend(setting, zsliderSetting); 
          $.extend(setting.callbacks, temp_callbacks); 
           
          itemLenght = setting.imagePanels.length; 
        } 
        //convert to the jquery object 
        setting.imagePanels = $(setting.imagePanels); 
        setting.ctrlItems = $(setting.ctrlItems); 
        setting.flipBtn.container = $(setting.flipBtn.container); 
        setting.flipBtn.preBtn = $(setting.flipBtn.preBtn); 
        setting.flipBtn.nextBtn = $(setting.flipBtn.nextBtn); 
      } 
      function initLook() { 
        //show the first image panel and hide other 
        setting.imagePanels.hide(); 
        setting.imagePanels.filter(':first').show(); 
        //activate the first control item and deactivate other 
        setting.ctrlItems.removeClass(setting.ctrlItemHoverCls); 
        setting.ctrlItems.filter(':first').addClass(setting.ctrlItemHoverCls); 
        $(that).css('overflow', 'hidden'); 
        if(setting.panelHoverShowFlipBtn) { 
          showFlipBtn(false); 
        } 
      } 
      function initEvent() { 
        $(concatArray(setting.imagePanels,  
            setting.flipBtn.preBtn, setting.flipBtn.nextBtn, true)).hover(function() { 
          if(setting.panelHoverStop) { 
            slider.stop(); 
          } 
          if(setting.panelHoverShowFlipBtn) { 
            showFlipBtn(true); 
          } 
        }, function() { 
          slider.start(); 
          if(setting.panelHoverShowFlipBtn) { 
            showFlipBtn(false); 
          } 
        }); 
        if(setting.ctrlItemActivateType === 'click') { 
          setting.ctrlItems.unbind('click'); 
          setting.ctrlItems.bind('click', function() { 
            slider.to($(this).index()); 
          }); 
        } else { 
          setting.ctrlItems.hover(function() { 
            slider.stop(); 
            slider.to($(this).index()); 
          }, function() { 
            slider.start(); 
          }); 
        } 
        setting.flipBtn.preBtn.unbind('click'); 
        setting.flipBtn.preBtn.bind('click', function() { 
          slider.pre(); 
        }); 
        setting.flipBtn.nextBtn.unbind('click'); 
        setting.flipBtn.nextBtn.bind('click', function() { 
          slider.next(); 
        }); 
      } 
      function init() { 
        initData(); 
         
        initLook(); 
         
        initEvent(); 
      } 
       
      function showFlipBtn(show) { 
        var hasContainer = setting.flipBtn.container.length > 0, 
          eles; 
        eles = hasContainer ? setting.flipBtn.container : 
          //to the dom array: 
          /*ARRAY_CONCAT.call(ARRAY_SLICE.apply(setting.flipBtn.preBtn), 
              ARRAY_SLICE.apply(setting.flipBtn.nextBtn));*/ 
          concatArray(setting.flipBtn.preBtn,  
                  setting.flipBtn.nextBtn, true); 
        if(show) { 
          $(eles).show(); 
        } else { 
          $(eles).hide(); 
        } 
      } 
       
      init(); 
      if(arguments.length < 2 || !!autoStart){ 
        slider.start(); 
      } 
      return slider; 
    } 
  }); 
})(jQuery, window, document);
Javascript 相关文章推荐
jQuery+CSS实现菜单滑动伸展收缩(仿淘宝)
Mar 22 Javascript
jquery选择器、属性设置用法经验总结
Sep 08 Javascript
js中Image对象以及对其预加载处理示例
Nov 20 Javascript
Java中Timer的用法详解
Oct 21 Javascript
jQuery结合CSS制作动态的下拉菜单
Oct 27 Javascript
很棒的js Tab选项卡切换效果
Aug 30 Javascript
js中scrollTop()方法和scroll()方法用法示例
Oct 03 Javascript
bootstrap的常用组件和栅格式布局详解
May 02 Javascript
underscore之function_动力节点Java学院整理
Jul 11 Javascript
vue-router路由懒加载和权限控制详解
Dec 13 Javascript
Vue中全局变量的定义和使用
Jun 05 Javascript
原生JS实现微信通讯录
Jun 18 Javascript
使用jQuery UI库开发Web界面的简单入门指引
Apr 22 #Javascript
jQuery 监控键盘一段时间没输入
Apr 22 #Javascript
基于jquery实现轮播特效
Apr 22 #Javascript
jquery插件Jplayer使用方法简析
Apr 22 #Javascript
jQuery点击其他地方时菜单消失的实现方法
Apr 22 #Javascript
JS验证逗号隔开可以是中文字母数字
Apr 22 #Javascript
JS简单循环遍历json数组的方法
Apr 22 #Javascript
You might like
用Socket发送电子邮件(利用需要验证的SMTP服务器)
2006/10/09 PHP
一个用于mysql的数据库抽象层函数库
2006/10/09 PHP
php打印一个边长为N的实心和空心菱型的方法
2015/03/02 PHP
ext 列表页面关于多行查询的办法
2010/03/25 Javascript
正则表达式搭配js轻松处理json文本方便而老古
2013/02/17 Javascript
jQuery prev ~ siblings选择器使用介绍
2013/08/09 Javascript
js截取固定长度的中英文字符的简单实例
2013/11/22 Javascript
MVVM模式中ViewModel和View、Model有什么区别?
2015/06/19 Javascript
SpringMVC restful 注解之@RequestBody进行json与object转换
2015/12/10 Javascript
如何使用Bootstrap的modal组件自定义alert,confirm和modal对话框
2016/03/01 Javascript
谈谈因Vue.js引发关于getter和setter的思考
2016/12/02 Javascript
jQuery Easyui datagrid连续发送两次请求问题
2016/12/13 Javascript
Canvas实现放射线动画效果
2017/02/15 Javascript
jquery+css实现侧边导航栏效果
2017/06/12 jQuery
Vue2.0 vue-source jsonp 跨域请求
2017/08/04 Javascript
js实现鼠标移动到图片产生遮罩效果
2017/10/21 Javascript
Angular HMR(热模块替换)功能实现方法
2018/04/04 Javascript
vue打包的时候自动将px转成rem的操作方法
2018/06/20 Javascript
vue实现组件之间传值功能示例
2018/07/13 Javascript
详解vue 兼容IE报错解决方案
2018/12/29 Javascript
JS中数据结构与算法---排序算法(Sort Algorithm)实例详解
2019/06/17 Javascript
详解node和ES6的模块导出与导入
2020/02/19 Javascript
详解js中的原型,原型对象,原型链
2020/07/16 Javascript
[36:13]Mineski vs iG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python 匹配任意字符(包括换行符)的正则表达式写法
2009/10/29 Python
基于CSS3实现立方体自转效果
2016/03/01 HTML / CSS
《小池塘》教学反思
2014/02/28 职场文书
2014年教研活动总结范文
2014/04/26 职场文书
企业读书活动总结
2014/06/30 职场文书
社会工作专业求职信
2014/07/15 职场文书
奉献家乡演讲稿
2014/09/13 职场文书
个人股份转让协议书范本
2014/10/26 职场文书
庐山导游词
2015/02/03 职场文书
山楂树之恋观后感
2015/06/11 职场文书
校园安全主题班会
2015/08/12 职场文书
Win11 Beta 预览版 22621.575 和 22622.575更新补丁KB5016694发布(附更新内容大全)
2022/08/14 数码科技