Подтвердить что ты не робот

Концепции ползунка бесконечности

Интересно, каковы наилучшие (хороший читаемый код, практика вредоносного кода, многократное использование) для создания бесконечного изображения-Loop-Slider для веб-сайта с использованием JavaScript/jQuery? Я не знаю, как закодировать слайд-шоу, но какой чертеж соответствует указанным выше требованиям.  Основное внимание в моем вопросе заключается в том, как упорядочить фотографии, чтобы получить впечатление бесконечного цикла Slider.

Посмотрев код из разных слайдеров, я столкнулся с двумя решениями:

-изменять z-индекс всех изображений каждый раз, когда отображается следующее/предыдущее изображение.

- изменить положение изображения в DOM.

Но изучить и понять код других очень трудоемко - вот почему я задаю этот вопрос: -)

4b9b3361

Ответ 1

tl; dr - Пример: http://jsbin.com/ufoceq/8/


Простой подход к созданию бесконечного слайдера изображения без особых усилий заключается в следующем: позвольте сказать, для простоты, что у вас есть <n> изображения для скольжения в цикле, так что после n th следующий для визуализации - это 1 st (и наоборот).

Идея состоит в том, чтобы создать клон первого и последнего изображений, чтобы

  • клон последнего изображения добавляется до первого;
  • клон первого изображения добавляется после последнего.

Каким бы ни был объем ваших изображений, вам нужно будет добавить не более 2 клонированных элементов.

Снова для простоты скажем, что все изображения 100px широкие, и они завернуты в контейнер, который вы перемещаете влево/вправо в обрезанную маску с помощью overflow: hidden. Затем все изображения можно легко выровнять в строке с display: inline-block и white-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: -100px или даже лучше (в зависимости от производительности) transform: translateX(-100px)), поэтому ползунок может отображать первое изображение. Чтобы переключиться с изображения на другой, вам необходимо применить анимацию javascript по тому же свойству, которое вы ранее выбрали.

Когда ваш слайдер в настоящее время находится на 4 th изображении, вам нужно переключиться с изображения 4 на 1c, поэтому идея состоит в том, чтобы выполнить обратный вызов в конце анимации, скоро переместите свою ползунок на реальное смещение изображения 1 st (например, вы установите left: -100px в контейнер)

Это аналогично, когда ваш слайдер в настоящее время расположен на элементе 1 st: для показа предыдущего изображения вам просто нужно выполнить анимацию с изображения 1 до 4c, и когда анимация завершен, вы просто перемещаете контейнер, так что слайдер неподвижно расположен на смещении изображения 4 th (например, вы устанавливаете left: -400px в контейнер).


Вы можете увидеть эффект на приведенном выше скрипте: это минимальный код js/jquery, который я использовал (конечно, код может быть даже оптимизирован, поэтому ширина элементов не жестко закодирована в script)

$(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 при инициализации ползунка и некоторые (довольно тривиальные ) дополнительная логика для управления обратным/прямым контуром.

Я не знаю, существует ли более простой или лучший подход, но надеюсь, что это все равно поможет.

Примечание: если вам нужна также отзывчивая галерея, возможно этот ответ может помочь также

Ответ 2

Я только что создал ползунок элемента: проверьте его: https://github.com/lingtalfi/jItemSlider/blob/master/README.md

Это 600 строк кода, возможно, вы можете просто просмотреть его.

Идея, стоящая за ней, вдохновлена ​​слайдером netflix (по состоянию на 2016-02-24).

В основном, он использует трансляции трансляции css, потому что это самые быстрые /slickest в браузере.

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

Кроме того, это элемент, основанный (а не на основе пикселей), и, в конце концов, то, что пользователь ожидает, потому что все всегда выровнено, как и должно быть.

Ответ 3

Большое спасибо этой статье! У меня было обновление и использование выше кода. Надеюсь, это поможет всем. Плохой разработчик.

<!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>