2013-04-08 78 views
22

我不知道是什么是最好的(好可读的代码,病虫害实践代码的可重用性)的概念来打造一个无限 - 图片 - 环 - 滑块使用JavaScript/jQuery的一个网站?我不知道如何编码幻灯片,但是什么蓝图符合上述要求。 我的问题的主要焦点是如何安排图片以获得无限循环滑块的印象。无限循环滑块概念

通过看代码从不同的滑块我遇到了两个解决方案:

- 更改所有图像的z-index的每个显示下一/上一个影像的时间。

- 更改图像在DOM中的位置。

但审视和理解他人的代码是非常耗时的 - 这就是为什么我问这个问题:-)

回答

49

TL;博士 - 例如:http://jsbin.com/ufoceq/8/


一个简单的方法来创建一个无限的图像滑块没有太多的努力,如下所示:让我们说,为了简单起见,您有<n>图像在循环中滑动,以便在nth想象的下一张照片是1st(反之亦然)。

的想法是让

  • 最后一个图像的克隆的第一个之前被预先计划建立第一个和最后图像的克隆;
  • 第一张图片的克隆被追加到最后一张图片的后面。

无论您的图片的数量是多少,您至少需要追加2个克隆元素。

再一次为了简单起见,假设所有图像都是100px宽,并且它们被包装在一个容器中,您可以左右移动到与overflow: hidden相关的修剪遮罩中。然后,所有图像可以很容易地与容器上的display: inline-blockwhite-space: nowrap对齐(现在更容易使用flexbox)。

对于n = 4 DOM结构是这样的:

offset(px)  0  100  200  300  400  500 
images   | 4c | 1 | 2 | 3 | 4 | 1c 

/*     ^^          ^^ 
     [ Clone of the last image ]    [ Clone of the 1st image ] 
*/ 

在开始的时候,您的容器将被定位left: -100px(或者也margin-left: -100pxor even better (for a matter of performance)transform: translateX(-100px)),因此滑块可以显示第一张图像。要从一个图像切换到另一个,您需要在您之前选择的同一个属性上应用JavaScript动画。

当你的滑盖是目前在4 形象,你必须从图像4切换到1c,这样的想法是在动画结束不久,在真正的重新定位你的滑盖包装执行的回调1 st图像偏移(例如您设置left: -100px到容器)

这类似于当你滑板目前位于1 ST元素:显示你只需要从图像1执行动画4c以前的形象,当动画已完成您只需移动容器,以便滑块位于图像偏移量(例如,将left: -400px设置为容器)。


你可以看到上面的小提琴效果:这是最小js/jquery代码我使用(当然代码甚至可以优化,使项目的宽度没有硬编码到脚本)

$(function() { 

    var gallery = $('#gallery ul'), 
     items = gallery.find('li'), 
     len  = items.length, 
     current = 1, /* the item we're currently looking */ 

     first = items.filter(':first'), 
     last = items.filter(':last'), 

     triggers = $('button'); 

    /* 1. Cloning first and last item */ 
    first.before(last.clone(true)); 
    last.after(first.clone(true)); 

    /* 2. Set button handlers */ 
    triggers.on('click', function() { 

    var cycle, delta; 

    if (gallery.is(':not(:animated)')) { 

     cycle = false; 
     delta = (this.id === "prev")? -1 : 1; 
     /* in the example buttons have id "prev" or "next" */ 

     gallery.animate({ left: "+=" + (-100 * delta) }, function() { 

      current += delta; 

      /** 
      * we're cycling the slider when the the value of "current" 
      * variable (after increment/decrement) is 0 or when it exceeds 
      * the initial gallery length 
      */   
      cycle = !!(current === 0 || current > len); 

      if (cycle) { 
       /* we switched from image 1 to 4-cloned or 
        from image 4 to 1-cloned */ 
       current = (current === 0)? len : 1; 
       gallery.css({left: -100 * current }); 
      } 
     }); 
    } 

    }); 
}); 

正如前面提到的,这种解决方案并不需要真正的精力和谈论的性能,而无需循环这种方法比较正常滑块,它只需要做两个额外的DOM插入时滑块初始化一些(相当triv ial)额外的逻辑来管理后向/前向循环。

我不知道是否存在一个更简单或更好的方法,但希望这有助于反正。

注意:如果您还需要有一个响应画廊,也许this answer可以帮助过

+0

谢谢您的详细解释! – user1828928 2013-04-08 12:08:41

+0

@ user1828928如果您对现场示例感兴趣,我创建了一个短小提琴 – fcalderan 2013-04-09 09:11:51

+0

对不起第一个标志。我认为电线已经穿过那里,因为你对这里的wiki地位是正确的。 – 2013-04-10 01:19:48

1

非常感谢这篇文章的! 我有更新并使用上面的代码。 我希望这会帮助大家。 差劲的开发人员。

<!DOCTYPE html> 
 
<html> 
 
<head lang="en"> 
 
    <meta charset="UTF-8"> 
 
    <title>Directive slider</title> 
 
    <style> 
 
     /* 四联切换焦点图 */ 
 
     .slides-wrapper{ position: relative; width: 100%; margin: 10px 0; } 
 
     .gallery { position: relative; width: 1200px; height: 180px; overflow:hidden; } 
 
     .gallery ul { font-size: 0; white-space: nowrap; position: absolute; top: 0; left: -1200px; margin: 0; padding: 0; } 
 
     .gallery li { display: inline-block; vertical-align: top; width: 1200px; height: 180px; white-space: normal; } 
 
     .gallery li img{ width: 298px; height:180px; padding: 1px; } 
 
     .gallery .arrow { background: url(/shop/templates/default/images/home_bg.png) no-repeat; background-size: 150px 223px; width: 35px; height: 70px; position: absolute; z-index: 2; top: 50px; cursor: pointer; opacity: 0;} 
 
     .gallery .prev { background-position: 1px -92px; left: 0;} 
 
     .gallery .next { background-position: -30px -92px; right: 0px;} 
 
    </style> 
 
    <style type="text/css"> 
 
     .demo_wrapper{ 
 
      margin: 0 auto; 
 
      width: 1200px; 
 
     } 
 
     .demo_wrapper .title{ 
 
      text-align: center; 
 
     } 
 
    </style> 
 
</head> 
 
<body> 
 
<div class="demo_wrapper"> 
 
    <div class="title"> 
 
     <h1>Directive slider (Published by fenmingyu)</h1> 
 
    </div> 
 
    <!-- demo content --> 
 
    <div class="slides-wrapper"> 
 
     <div class="gallery" id="top_sale_gallery"> 
 
      <ul> 
 
       <li> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-1.jpg?234" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-2.jpg?752" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-3.jpg?320" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-4.jpg?365" alt=""></a> 
 
       </li> 
 
       <li> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-1.jpg?852" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-2.jpg?746" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-3.jpg?525" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-4.jpg?550" alt=""></a> 
 
       </li> 
 
      </ul> 
 
      <div class='arrow prev'></div> 
 
      <div class='arrow next'></div> 
 
     </div> 
 
     <div class="gallery" id="top_goods_gallery"> 
 
      <ul> 
 
       <li> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-1.jpg?793" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-2.jpg?180" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-3.jpg?550" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-4.jpg?851" alt=""></a> 
 
       </li> 
 
       <li> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-1.jpg?234" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-2.jpg?752" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-3.jpg?320" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-4.jpg?365" alt=""></a> 
 
       </li> 
 
       <li> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-1.jpg?852" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-2.jpg?746" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-3.jpg?525" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-4.jpg?550" alt=""></a> 
 
       </li> 
 
      </ul> 
 
      <div class='arrow prev'></div> 
 
      <div class='arrow next'></div> 
 
     </div> 
 
     <div style="clear: both;"></div> 
 
    </div> 
 
</div> 
 

 
</body> 
 
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 
 
<script type="text/javascript"> 
 
    $(function() { 
 
     $.fn.gallery = function(settings) { 
 
      var defaults = { 
 
       time: 3000, 
 
       direction:1 
 
      }; 
 
      var settings = $.extend(defaults, settings); 
 
      var gallery_wrapper = $(this), 
 
       gallery = gallery_wrapper.find('ul'), 
 
       items = gallery.find('li'), 
 
       len  = items.length, 
 
       current = 1, /* the current item we're looking */ 
 
       first = items.filter(':first'), 
 
       last = items.filter(':last'), 
 
       w = gallery.find('li').width(), 
 
       triggers = gallery_wrapper.find('.arrow'); 
 
      var show_slide = function(direction,w){ 
 
       gallery.animate({ left: "+=" + (-w * direction) }, function() { 
 

 
        current += direction; 
 

 
        /** 
 
        * we're cycling the slider when the the value of "current" 
 
        * variable (after increment/decrement) is 0 or when it exceeds 
 
        * the initial gallery length 
 
        */ 
 
        cycle = !!(current === 0 || current > len); 
 

 
        if (cycle) { 
 
         /* we switched from image 1 to 4-cloned or 
 
         from image 4 to 1-cloned */ 
 
         current = (current === 0)? len : 1; 
 
         gallery.css({left: -w * current }); 
 
        } 
 
       }); 
 
      }; 
 
      var picTimer = setInterval(function() { 
 
         show_slide(settings.direction,w); 
 
        }, 
 
        settings.time); 
 
      return this.each(function(){ 
 

 
       /* 1. Cloning first and last item */ 
 
       first.before(last.clone(true)); 
 
       last.after(first.clone(true)); 
 
       /* 2. Set button handlers */ 
 
       triggers.on('click', function() { 
 
        if (gallery.is(':not(:animated)')) { 
 

 
         var cycle = false; 
 
         settings.direction = ($(this).hasClass('prev'))? -1 : 1; 
 
         /* in the example buttons have id "prev" or "next" */ 
 
         show_slide(settings.direction,w); 
 
        } 
 
        clearInterval(picTimer); 
 
        picTimer = setInterval(function() { 
 
           show_slide(settings.direction,w); 
 
          }, 
 
          settings.time); 
 
       }); 
 
       /* hover show arrows*/ 
 
       show_slide(settings.direction,w); 
 

 
       gallery_wrapper.hover(function() { 
 
        $(this).find(".arrow").css("opacity", 0.0).stop(true, false).animate({ 
 
           "opacity": "0.3" 
 
          }, 
 
          300); 
 
       },function(){ 
 
        $(this).find(".arrow").css("opacity", 0.3).stop(true, false).animate({ 
 
           "opacity": "0" 
 
          }, 
 
          300); 
 
       }); 
 
      }); 
 
     }; 
 
     $('#top_goods_gallery.gallery').gallery(); 
 
     $('#top_sale_gallery.gallery').gallery({ 
 
      time: 5000, 
 
      direction:-1 
 
     }); 
 
    }); 
 
</script> 
 
</html>

TE和在我的项目中使用这个。

2

我刚刚创建的项目滑块:检查出来: https://github.com/lingtalfi/jItemSlider/blob/master/README.md

它的代码600线,也许你可以简单地浏览它。

它背后的想法是受netflix滑块(截至2016年2月24日)的启发。

基本上,它使用css转换翻译,因为这些是浏览器中最快/最清晰的翻译。

http://eng.wealthfront.com/2015/05/19/performant-css-animations/

现在滑运动背后的基本理念是,你只显示当前可见切片, 但你也有左边一个无形的切片,并在右侧的另一个无形的切片。

而且,你也有两个额外的项目,一边一个,让你的项目是这样的:

以前的项目 - 上一个额外的项目 - 主要项目 - 下一个额外的项目 - 下一个项目

只有主要项目可见。 额外的项目部分可见。 上一个和下一个项目是不可见的。

更多细节在这里: https://github.com/lingtalfi/jItemSlider/blob/master/doc/conception.md

现在,当你向右滑动(例如),你基本上更多的项目添加到右侧, 然后删除那些从左侧。

这个技术是迄今为止我遇到过的最大的技术,因为你不需要处理一长串物品(使用 克隆而不移除隐形物品),这可以使动画变慢。

注:我这个滑块的第一次尝试,实际上克隆不删除,它的工作原理,但我不喜欢它: https://github.com/lingtalfi/jInfiniteSlider

此外,它是基于(而不是基于像素)项目,并在最终,这就是用户期望的,因为 一切都始终保持一致,因为它应该是。