使用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技巧来提高你的代码(个人觉得那个jquery的手册很不错)
Feb 10 Javascript
Three.js源码阅读笔记(物体是如何组织的)
Dec 27 Javascript
利用jQuery的deferred对象实现异步按顺序加载JS文件
Mar 17 Javascript
jQuery制作的别致导航有阴影背景高亮模式窗口
Apr 15 Javascript
关于img的href和src取变量及赋值的方法
Apr 28 Javascript
JavaScript禁止复制与粘贴的实现代码
May 16 Javascript
解决给dom元素绑定click等事件无效问题的方法
Feb 17 Javascript
微信小程序 自动登陆PHP源码实例(源码下载)
May 08 Javascript
angularjs 页面自适应高度的方法
Jan 17 Javascript
微信小程序常见页面跳转操作简单示例
May 01 Javascript
解决IOS端微信H5页面软键盘弹起后页面下方留白的问题
Jun 05 Javascript
一篇文章了解正则表达式的替换技巧
Feb 24 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
php中foreach结合curl实现多线程的方法分析
2016/09/22 PHP
PHP实现分布式memcache设置web集群session同步的方法
2018/04/10 PHP
PHP5.0~5.6 各版本兼容性cURL文件上传功能实例分析
2018/05/11 PHP
javascript 节点遍历函数
2010/03/28 Javascript
通过JavaScript控制字体大小的代码
2011/10/04 Javascript
js采用map取到id集合组并且实现点击一行选中一行
2013/12/16 Javascript
JS 数字转换研究总结
2013/12/26 Javascript
用JavaScript实现用一个DIV来包装文本元素节点
2014/09/09 Javascript
原生js制作简单的数字键盘
2015/04/24 Javascript
javascript实现手机震动API代码
2015/08/05 Javascript
js实现有过渡渐变效果的图片轮播相册(兼容IE,ff)
2016/01/19 Javascript
JavaScript中Object.prototype.toString方法的原理
2016/02/24 Javascript
JS+canvas绘制的动态机械表动画效果
2017/09/12 Javascript
Vue封装Swiper实现图片轮播效果
2018/02/06 Javascript
基于jQuery实现Ajax验证用户名是否可用实例
2018/03/25 jQuery
简单的三步vuex入门
2018/05/20 Javascript
Vue.js 中取得后台原生HTML字符串 原样显示问题的解决方法
2018/06/10 Javascript
Vue打包后访问静态资源路径问题
2019/11/08 Javascript
Vue切换div显示隐藏,多选,单选代码解析
2020/07/14 Javascript
Angular利用HTTP POST下载流文件的步骤记录
2020/07/26 Javascript
[01:03:51]2018DOTA2亚洲邀请赛 4.7 淘汰赛 VP vs LGD 第三场
2018/04/09 DOTA
Windows8下安装Python的BeautifulSoup
2015/01/22 Python
浅谈python中的占位符
2017/11/09 Python
pyqt5自定义信号实例解析
2018/01/31 Python
python实现彩票系统
2020/06/28 Python
python pandas库的安装和创建
2019/01/10 Python
Django之choices选项和富文本编辑器的使用详解
2020/04/01 Python
Java中采用什么结构来捕获、处理异常?各子句的顺序、功能如何
2013/10/07 面试题
四种会话跟踪技术
2015/05/20 面试题
个人简历自我评价八例
2013/10/31 职场文书
致长跑运动员广播稿
2014/01/31 职场文书
订货会邀请函
2015/01/31 职场文书
2015年人力资源工作总结
2015/04/08 职场文书
学习心理学心得体会
2016/01/22 职场文书
商业计划书格式、范文
2019/03/21 职场文书
mysql对于模糊查询like的一些汇总
2021/05/09 MySQL