无限循环滑块概念

时间:2013-04-08 10:24:45

标签: javascript jquery html css

我想知道使用JavaScript / jQuery为网站构建Infinity-Image-Loop-Slider的最佳(良好可读代码,害虫练习代码,可重用性)概念是什么?我不知道如何编写幻灯片的代码,但是什么蓝图符合上面提到的要求。  我的问题的主要焦点是如何安排图片以获得无限循环滑块的印象。

通过查看不同Sliders的Code,我遇到了两个解决方案:

- 每次显示下一张/上一张图像时,更改所有图像的z-Index。

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

但是检查和理解他人的代码非常耗时 - 这就是我问这个问题的原因: - )

3 个答案:

答案 0 :(得分:58)

  

tl; dr - 示例:http://jsbin.com/ufoceq/8/


创建无限图像滑块而不需要太多努力的简单方法如下:为简单起见,假设您有<n>个图像在循环中滑动,以便在{{1}之后} th 图像下一个可视化的是n st (反之亦然)。

这个想法是创建第一个和最后一个图像的克隆,以便

  • 最后一张图片的克隆前置于第一张图片之前;
  • 第一张图片的克隆将附加在最后一张图片之后。

无论你的图像数量是多少,你最多只需要添加2个克隆元素。

再次为简单起见,假设所有图像都是1宽并且它们被包裹在一个容器中,您可以使用100px左/右移动到剪切的蒙版中。然后,所有图片都可以轻松排成一行,并在容器上设置overflow: hiddendisplay: inline-block(现在更容易使用white-space: nowrap。)

对于flexbox DOM结构将是这样的:

n = 4

一开始,您的容器将定位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 or even better (for a matter of performance) margin-left: -100px),因此滑块可以显示第一张图片。要从图像切换到另一个图像,您需要在之前选择的同一属性上应用javascript动画。

当您的滑块当前位于4 th 图像时,您必须从图像transform: translateX(-100px)切换到4,因此我们的想法是在最后执行回调很快就会在真正的1 st 图像偏移处重新定位滑块包装的动画(例如,您将1c设置为容器)

当滑块当前位于1 st 元素上时,这类似:要显示上一张图像,您只需执行从图像left: -100px1的动画当动画完成后,您只需移动容器,使滑块显然位于4 th 图像偏移处(例如,您将4c设置为容器)。


你可以看到对上面小提琴的影响:这是我使用的最小left: -400px代码(当然代码甚至可以优化,所以项目的宽度不会硬编码到脚本中)

js/jquery

如前所述,这个解决方案不需要太多努力和谈论性能,将此方法与普通滑块进行比较而不进行循环,只需要在滑块初始化时进行两次额外的DOM插入(一些非常简单) )管理后向/前向循环的额外逻辑。

我不知道是否存在更简单或更好的方法,但希望无论如何都有帮助。

注意:如果您还需要一个自适应图库,也许this answer可能会有所帮助

答案 1 :(得分:3)

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

这是600行代码,也许你可以简单地浏览它。

背后的想法受netflix滑块的启发(截至2016-02-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

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

答案 2 :(得分:0)

非常感谢这篇文章! 我有更新并使用上面的代码。 我希望这对每个人都有帮助。 可怜的开发者。

<!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并在我的项目中使用它。