zoukankan      html  css  js  c++  java
  • 响应式轮播unslider使用方法2

    一、如何使用

    第1步:导入类库

    Unslider是基于jQuery,自然要先将Jquery库导入

    [javascript] view plain copy
     
     print?
    1. <script src="http://code.jquery.com/jquery-latest.min.js"></script>  
    2. <script src="http://unslider.com/unslider.js"></script>  


    第2步:写HTML结构,即幻灯片列表

    [html] view plain copy
     
     print?
    1. <div class="banner">  
    2.     <ul>  
    3.         <li style="background:url(1.jpg)">first slide.</li>  
    4.         <li style="background:url(2.jpg)">second slide.</li>  
    5.         <li style="background:url(3.jpg)">third slide.</li>  
    6.     </ul>  
    7. </div>  

    第3步:添加样式,这里先不管漂亮,只放官网上说必须有的骨架

    [css] view plain copy
     
     print?
    1. .banner { position: relative; overflow: auto; }  
    2. .banner li { list-style: none; }  
    3. .banner ul li { float: left; }  

    第4步:调用unslider()方法让幻灯片列表滚动起来,参数就先默认吧

    [javascript] view plain copy
     
     print?
    1. $(function() {  
    2.     $('.banner').unslider();  
    3. });  


    好了,到这里幻灯片就如预期滚动起来了。但是不美观,为了更加灵活定制自己想要的效果,我要潜入源代码瞧一瞧。

    二、源码分析

    [javascript] view plain copy
     
     print?
    1. /** 
    2.  *   Unslider by @idiot and @damirfoy 
    3.  *   Contributors: 
    4.  *   - @ShamoX 
    5.  * 
    6.  */  
    7.   
    8. (function($, f) {  
    9.     var Unslider = function() {  
    10.         //  克隆对象  
    11.         var _ = this;  
    12.   
    13.         //  设置一些默认参数  
    14.         _.o = {  
    15.             speed: 500,     // 动画过渡的速度(毫秒),如果不需要过渡效果就设置为false  
    16.             delay: 3000,    // 每张幻灯片的间隔时间(毫秒), 如果不是自动播放就设置为false  
    17.             init: 0,        // 初始化延迟时间(毫秒),如果不需要延迟就设置为false  
    18.             pause: !f,      // 当鼠标指针浮动在当前区域内时是否暂停自动播放  
    19.             loop: !f,       // 是否无尽循环播放  
    20.             keys: f,        // 是否开启键盘导航  
    21.             dots: f,        // 是否显示导航点  
    22.             arrows: f,      // 是否显示向前和向后的箭头  
    23.             prev: '←',     // 向前按钮中的显示文字(或html片段)  
    24.             next: '→',     // 向后......  
    25.             fluid: f,       // 是否宽度自适应  
    26.             starting: f,    // 在每个动画前调用的函数  
    27.             complete: f,    // 在每个动画之后调用的函数  
    28.             items: '>ul',   // 幻灯片的容器选择器  
    29.             item: '>li',    // 需要滚动的选择器  
    30.             easing: 'swing',// 动画的缓动函数(easing function)  
    31.             autoplay: true  // 是否允许自动播放  
    32.         };  
    33.   
    34.         _.init = function(el, o) {  
    35.             //  将我们在外部调用时设置的参数覆盖掉默认参数  
    36.             _.o = $.extend(_.o, o);  
    37.   
    38.             _.el = el;  
    39.             _.ul = el.find(_.o.items);//返回ul元素集合  
    40.             _.max = [el.outerWidth() | 0, el.outerHeight() | 0];//保存一下幻灯片div容器的宽和高  
    41.             _.li = _.ul.find(_.o.item).each(function(index) {  
    42.                 var me = $(this),  
    43.                     width = me.outerWidth(),  
    44.                     height = me.outerHeight();  
    45.   
    46.                 //  记录最大幻灯片的宽高  
    47.                 if (width > _.max[0]) _.max[0] = width;  
    48.                 if (height > _.max[1]) _.max[1] = height;  
    49.             });  
    50.   
    51.   
    52.             //  申请一些临时变量  
    53.             var o = _.o,  
    54.                 ul = _.ul,  
    55.                 li = _.li,  
    56.                 len = li.length;//li元素个数  
    57.   
    58.             //  当前索引,或者叫页码更容易理解吧,源代码中写了“Current indeed”,应该是“index”吧  
    59.             _.i = 0;  
    60.   
    61.             //  设置幻灯片div容器的样式,高度初始化为第一个li的高度  
    62.             el.css({ _.max[0], height: li.first().outerHeight(), overflow: 'hidden'});  
    63.   
    64.             //  设置ul元素的位置和宽度,宽度的公式是(li元素的个数乘以100)%,我的例子中就是300%  
    65.             ul.css({position: 'relative', left: 0,  (len * 100) + '%'});  
    66.             if(o.fluid) {  
    67.                 li.css({'float': 'left',  (100 / len) + '%'});//自适应宽度时,li元素的宽度就是把ul的宽度平均分成len份  
    68.             } else {  
    69.                 li.css({'float': 'left',  (_.max[0]) + 'px'});//不是自适应时,li元素的宽度是最大的幻灯片的宽度  
    70.             }  
    71.   
    72.             //  在init毫秒后开启自动播放  
    73.             o.autoplay && setTimeout(function() {  
    74.                 if (o.delay | 0) {  
    75.                     _.play();  
    76.   
    77.                     if (o.pause) {  
    78.                         el.on('mouseover mouseout', function(e) {  
    79.                             _.stop();//鼠标经过时暂停  
    80.                             e.type == 'mouseout' && _.play();//鼠标离开时播放  
    81.                         });  
    82.                     };  
    83.                 };  
    84.             }, o.init | 0);  
    85.   
    86.             //  键盘事件处理  
    87.             if (o.keys) {  
    88.                 $(document).keydown(function(e) {  
    89.                     var key = e.which;  
    90.   
    91.                     if (key == 37)  
    92.                         _.prev(); // 左箭头按键  
    93.                     else if (key == 39)  
    94.                         _.next(); // 右箭头按键  
    95.                     else if (key == 27)  
    96.                         _.stop(); // Esc  
    97.                 });  
    98.             };  
    99.   
    100.             //  显示导航点  
    101.             o.dots && nav('dot');  
    102.   
    103.             //  显示箭头  
    104.             o.arrows && nav('arrow');  
    105.   
    106.             //  使幻灯片div容器宽度自适应  
    107.             if (o.fluid) {  
    108.                 $(window).resize(function() {  
    109.                     _.r && clearTimeout(_.r);  
    110.   
    111.                     _.r = setTimeout(function() {  
    112.                         var styl = {height: li.eq(_.i).outerHeight()},  
    113.                             width = el.outerWidth();  
    114.   
    115.                         ul.css(styl);  
    116.                         //这一串真是绕,其实就是计算div占父窗口的宽度原始比例,然后记录到styl中  
    117.                         styl['width'] = Math.min(Math.round((width / el.parent().width()) * 100), 100) + '%';  
    118.                         el.css(styl);//重新设置幻灯片div容器的宽度为比例而不是像素值,这样就能达到自适应的目的了  
    119.                         li.css({  width + 'px' });//设置li的绝对宽度,以防因div被自适应了而挤压或拉伸了li造成内容扭曲(如有误请大神指教)  
    120.                     }, 50);//每次父窗口改变大小时,幻灯片div容器延迟50毫秒后再跟着自适应大小,请大神告诉我这样做的目的仅仅是为了效果更自然么  
    121.                 }).resize();//强制执行resize事件,使得自适应特性在最开始时就被设置好了  
    122.             };  
    123.   
    124.             //  自定义move事件,这一段不太懂,求大神指点  
    125.             if ($.event.special['move'] || $.Event('move')) {  
    126.                 //  为幻灯片div元素绑定movestart、move、moveend事件  
    127.                 el.on('movestart', function(e) {  
    128.                     if ((e.distX > e.distY && e.distX < -e.distY) || (e.distX < e.distY && e.distX > -e.distY)) {  
    129.                         e.preventDefault();//鼠标位置不在当前区域时取消事件的默认动作(我猜的,关键是不知道distX这几个的准确含义)  
    130.                     }else{  
    131.                         el.data("left", _.ul.offset().left / el.width() * 100);  
    132.                     }  
    133.                 }).on('move', function(e) {  
    134.                         var left = 100 * e.distX / el.width();  
    135.                         var leftDelta = 100 * e.deltaX / el.width();  
    136.                         _.ul[0].style.left = parseInt(_.ul[0].style.left.replace("%", ""))+leftDelta+"%";  
    137.   
    138.                         _.ul.data("left", left);  
    139.                     }).on('moveend', function(e) {  
    140.                         var left = _.ul.data("left");//  
    141.                         if (Math.abs(left) > 30){  
    142.                             var i = left > 0 ? _.i-1 : _.i+1;  
    143.                             if (i < 0 || i >= len) i = _.i;  
    144.                             _.to(i);  
    145.                         }else{  
    146.                             _.to(_.i);  
    147.                         }  
    148.                     });  
    149.             };  
    150.   
    151.             return _;  
    152.         };  
    153.   
    154.         //  播放指定索引的幻灯片  
    155.         _.to = function(index, callback) {  
    156.             if (_.t) {  
    157.                 _.stop();  
    158.                 _.play();  
    159.             }  
    160.             var o = _.o,  
    161.                 el = _.el,  
    162.                 ul = _.ul,  
    163.                 li = _.li,  
    164.                 current = _.i,  
    165.                 target = li.eq(index);  
    166.             //在动画之前执行的函数,我的例子里都没有,可以忽略它们  
    167.             $.isFunction(o.starting) && !callback && o.starting(el, li.eq(current));  
    168.   
    169.             //  如果(一张幻灯片也没有或者索引无效),并且不是循环播放,就啥也不做,我觉得这样不好,因为to这个函数就只能在循环播放状态下工作了  
    170.             if ((!target.length || index < 0) && o.loop == f) return;  
    171.   
    172.             //  检查索引是否有效,超出时设置为0,即第一张幻灯片  
    173.             if (!target.length) index = 0;  
    174.             if (index < 0) index = li.length - 1;//索引负数时设置为最后一张幻灯片  
    175.             target = li.eq(index);//获取目标元素  
    176.   
    177.             var speed = callback ? 5 : o.speed | 0,//执行回调函数后返回的是真则speed设为5,如果没有回调函数或返回假则设置为o.speed  
    178.                 easing = o.easing,  
    179.                 obj = {height: target.outerHeight()};  
    180.   
    181.             if (!ul.queue('fx').length) {//确保没有为ul元素添加函数队列,应该是为了防止上一次动作还没有完成吧  
    182.                 //  设置对应导航点的高亮  
    183.                 el.find('.dot').eq(index).addClass('active').siblings().removeClass('active');  
    184.                 //  改变幻灯片div容器的高度为目标元素的高度,并把ul的位置向左移动(index*100%),使目标元素正好在幻灯片div容器区域  
    185.                 el.animate(obj, speed, easing) && ul.animate($.extend({left: '-' + index + '00%'}, obj), speed, easing, function(data) {  
    186.                     _.i = index;//移动结束之后更新一下当前索引  
    187.                     //动画结束之后执行的函数,我的例子中也没有,忽略它们  
    188.                     $.isFunction(o.complete) && !callback && o.complete(el, target);  
    189.                 });  
    190.             };  
    191.         };  
    192.   
    193.         //  每隔delay毫秒自动播放  
    194.         _.play = function() {  
    195.             _.t = setInterval(function() {  
    196.                 _.to(_.i + 1);//这里就加了1个索引号,具体的处理都封装在了to方法中  
    197.             }, _.o.delay | 0);  
    198.         };  
    199.   
    200.         //  停止自动播放  
    201.         _.stop = function() {  
    202.             _.t = clearInterval(_.t);  
    203.             return _;  
    204.         };  
    205.   
    206.         //  向后翻一张  
    207.         _.next = function() {  
    208.             return _.stop().to(_.i + 1);  
    209.         };  
    210.         //  向前翻一张  
    211.         _.prev = function() {  
    212.             return _.stop().to(_.i - 1);  
    213.         };  
    214.   
    215.         //  创建导航点和箭头  
    216.         function nav(name, html) {  
    217.             if (name == 'dot') {  
    218.                 html = '<ol class="dots">';  
    219.                 $.each(_.li, function(index) {  
    220.                     html += '<li class="' + (index == _.i ? name + ' active' : name) + '">' + ++index + '</li>';  
    221.                 });  
    222.                 html += '</ol>';  
    223.                 /*整理一下,在我的例子中就是这副摸样 
    224.                   <ol class="dots">            
    225.                   <li class="dot active">0</li> 
    226.                   <li class="dot">1</li> 
    227.                   <li class="dot">2</li> 
    228.                   </ol> 
    229.                 */  
    230.             } else {  
    231.                 html = '<div class="';  
    232.                 html = html + name + 's">' + html + name + ' prev">' + _.o.prev + '</div>' + html + name + ' next">' + _.o.next + '</div></div>';  
    233.                 /*也整理一下 
    234.                   <div class="arrows"> 
    235.                     <div class="arrow prev">←</div> 
    236.                     <div class="arrow next">→</div> 
    237.                   </div> 
    238.                 */  
    239.             };  
    240.             //先给幻灯片div容器元素加上has-dots或arrows的class,再把上面组织好的元素追加为子元素,并给该子元素添加click事件处理函数  
    241.             _.el.addClass('has-' + name + 's').append(html).find('.' + name).click(function() {  
    242.                 var me = $(this);  
    243.                 me.hasClass('dot') ? _.stop().to(me.index()) : me.hasClass('prev') ? _.prev() : _.next();  
    244.             });  
    245.         };  
    246.     };  
    247.   
    248.     //  将unslider方法扩展到jQuery对象,使任意jQuery对象都能够直接访问该方法,就像上面那样:$('.banner').unslider();  
    249.     $.fn.unslider = function(o) {  
    250.         var len = this.length;  
    251.   
    252.         //  遍历li元素集  
    253.         return this.each(function(index) {  
    254.             var me = $(this),  
    255.                 key = 'unslider' + (len > 1 ? '-' + ++index : ''),  
    256.                 instance = (new Unslider).init(me, o);  
    257.   
    258.             //  给div元素添加数据  
    259.             me.data(key, instance).data('key', key);  
    260.         });  
    261.     };  
    262.   
    263.     Unslider.version = "1.0.0";  
    264. })(jQuery, false);  

    三、定制自己需要的幻灯片

    终于看完大部分了。好了,通过源码至少我知道了该怎样去控制外观,现在我要动手啦,心里有点小激动呢~

    我选择Unslider是因为它是如此纯粹,正如我想要的那样,啥也可以不要,只要能自动循环播放、用导航点控制翻页就满足我的要求了。

    因为默认就是自动循环播放的,所以我只要设置一个显示导航点的参数即可,然后锦上添花也支持一下响应式吧:

    [javascript] view plain copy
     
     print?
    1. $(function() {  
    2.     $('.banner').unslider({  
    3.         dots: true,               //  显示导航点  
    4.         fluid: true               //  支持响应式设计  
    5.     });  
    6. });  


    通过源码我们知道unslider为我们写好了导航点的文档结构、并取好了类名,但并没有设置样式,所以只是传个参数是木有用滴,要自己写样式才能看见那些可爱的点点:

    [javascript] view plain copy
     
     print?
    1. *{margin: 0;padding: 0;}  
    2. .banner { position: relative; top:0;overflow: auto; }  
    3. .banner li { list-style: none; }  
    4. .banner ul li { float: left; }  
    5. .dots{66px;position:absolute;bottom:10px;left:50%;margin-left:-27px;}  
    6. .dot{  
    7.     display:inline-block;  
    8.      10px;  
    9.     height: 10px;  
    10.     font-size: 0px;  
    11.     line-height: 0px;  
    12.     margin-right: 12px;  
    13.     cursor: pointer;  
    14.     background-color: #ffffff;  
    15.     border-radius: 8px;  
    16. }  
    17. .dot.active{background-color: #cce8cf;}  
  • 相关阅读:
    用机器学习来预测一个活动的总交易额值
    点击率模型的二三事
    git教程
    shell的查找与替换
    python中列表和元组以及字符串的操作
    自然语言处理第一课
    shell入门
    python基础知识
    SQL指令中一些特别值得注意的地方
    【python】json
  • 原文地址:https://www.cnblogs.com/qingqinglanlan/p/7536612.html
Copyright © 2011-2022 走看看