Элемент слайдера цикла jquery / javascript - PullRequest
0 голосов
/ 11 января 2019

Я создал базовый слайдер с эффектом анимации,

Я использую transform: translate3d, чтобы переместить ползунок влево или вправо, и у меня возникла проблема, и он немного потерял в том, как заставить его вращаться и скользить влево или вправо бесконечно.

Я пытаюсь сделать так, чтобы при нажатии влево или вправо он продолжал показывать и поворачивать изображения.

Я также хотел иметь плавный переход с z-index, но это не представляется возможным.

Вот jsFiddle из того, что я сделал https://jsfiddle.net/wo67h4n9/

вот код HTML

<div class="vs-slider">
  <div class="vss-wrap">
    <div class="item active"><img src="http://lorempixel.com/430/280/sports" alt="Slider Item" width="430" height="280"></div>
    <div class="item"><img src="http://lorempixel.com/430/280/animals" alt="Slider Item" width="430" height="280"></div>
    <div class="item"><img src="http://lorempixel.com/430/280/nature" alt="Slider Item" width="430" height="280"></div>
  </div>
  <ul class="vss-nav">
    <li class="prev">&lt;</li>
    <li class="next">&gt;</li>
  </ul>
</div>

JQuery

;( function($) {
    $(document).ready(function() {
        $('.vs-slider .item').each( function() {
            $(this).css('z-index', $('.vs-slider .item').length - $('.vs-slider .item').index(this));
        });

        $('.vss-nav').on('click', '.prev, .next', function() {
            var active = $(this).closest('.vs-slider').find('.item.active');
            if ( $(this).hasClass('next') ) {
                vss_moveleft($('.vs-slider'));
                active.next().addClass('active');
            } else {
                vss_moveleft( $('.vs-slider'), 'right');
                active.prev().addClass('active');
            }
            active.removeClass('active');
        });

        function vss_moveleft( slider, type = 'left' ) {
            var itemWidth = slider.find('.item').outerWidth() - 299,
            itemTotal = slider.find('.item').length,
            currentOff = slider.find('.vss-wrap').position().left,
            movemVal = type === 'left' ? currentOff - itemWidth : currentOff + itemWidth;
            slider.find('.vss-wrap').css('transform', 'translate3d('+ movemVal +'px, 0px, 0px)');

        }
    });
})(jQuery);

CSS

body {
  background: #222
}
.vs-slider {
  position: relative;
  overflow: hidden;    
  max-height: 290px;
  max-width: 500px;
}
.vs-slider img {
    margin: 0;
    vertical-align: top;
}
.vs-slider .vss-wrap {
    min-width: 90VW;
    transform: translate3d(0px, 0px, 0px);
    transition: all 0.5s ease 0s;
}
.vs-slider .vss-wrap::after {
    clear: both;
    width: 100%;
    display: block;
    content: "";
}
.vs-slider .item {
    float: left;
    border: 1px solid #fff;
    transform: scale(.7);
    position: relative;
    z-index: 1;
    transition: all 1s ease 0s;
    margin-right: -299px;
}
.vs-slider .item.active {
    transform: scale(1);
    z-index: 20 !important;
}
.vs-slider .item:not(.active) {
    z-index: 0;
    cursor: pointer;
}
.vss-nav {
    position: absolute;
    margin: 0;
    padding: 0;
    right: 5px;
    bottom: 0;
}
.vss-nav li {
    display: inline-block;
    color: #fff;
    margin: 0 5px;
    cursor: pointer;
}

Буду признателен за любую помощь.

Спасибо

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Эй, какой интересный вопрос ты задал, тебе нужно заботиться о некоторых вещах, чтобы достичь своей цели, поэтому я объясню, чего тебе не хватает.

  1. Вы можете использовать чистый CSS, чтобы применить переход без JS, так что вам нужно: Селекторы братьев и сестер , это поможет вам применять стили ко всем элементам с правой стороны определенного элемента.

Например: представьте, что у нас есть простая разметка вроде

<div>
  <div class="item active">
  </div>
  <div class="item">
  </div>
  <div class="item">
  </div>
  <div class="item">
  </div>
</div>

// Styles.css

.item.active ~ .item {
  background: blue;
}

Приведенный выше стиль будет применяться ко всем элементам с классом item справа от элемента .item.active

  1. Применить стили для всех классов item, которые будут применены, чтобы бросить их в левую сторону.

  2. Применить стиль для элемента .item.active, который будет отображаться только.

  3. Чтобы сделать слайдер бесконечным, вам нужно проверить, когда пользователь нажимает кнопку «Далее» и «Предыдущая», и проверять, когда пользователь достигнет конца на следующем или на элементах «предыдущий», тогда вам нужно взять первый элемент. и поместите его в конце для следующего случая, и возьмите последний элемент и поместите его в начале в предыдущем случае.

  4. Вам нужно проверить, если при запуске ползунка, активен ли первый элемент, нужно ли клонировать все элементы и поместить их в обратном порядке непосредственно перед первым элементом.

Итак, больше слов, здесь вам нужен рабочий пример, который очень поможет вам понять эту функцию для вашего бесконечного слайдера.

;( function($) {
    $(document).ready(function() {
    		/*
        This function will check if the active class is in the first element then we will clone all elements at the left side of the first element to make it circular sliding
        */
      	function cloneElementsIfStartAtZero() {
          var firstItem = $('.item').first();
          var isActiveFirst = firstItem.hasClass('active');

          if (isActiveFirst) {
            var last = firstItem;
            $($('.item').get().reverse()).each(function(){
              var current = $(this).clone().removeClass('active');
              last.before(current);
              last = current;
            });
          }
        }
    
    		cloneElementsIfStartAtZero();

        $('.vss-nav').on('click', '.prev, .next', function() {
        		// we get the active, first, and last elements
            var active = $('.item.active');
            var first = $('.item').first();
            var last = $('.item').last();
            
            // if click at next arrow
            
            if ( $(this).hasClass('next') ) {
            		// check if next element is the last, then take the first element and set it to the last element
                if(active.next().next().length === 0) {
                	last.after(first);
                }
                // apply active class to make transition
                active.next().addClass('active');
            } else {
            		// check if prev element is the first, then take last element and set it before the first element
            		if(active.prev().length === 0 || active.prev().prev().length === 0) {
                	first.before(last);
                }
                // then appy active class to apply transition
								active.prev().addClass('active');
            }
            active.removeClass('active');
        });

        function vss_moveleft( slider, type = 'left' ) {
            var itemWidth = slider.find('.item').outerWidth() - 299,
            itemTotal = slider.find('.item').length,
            currentOff = slider.find('.vss-wrap').position().left,
            movemVal = type === 'left' ? currentOff - itemWidth : currentOff + itemWidth;
            slider.find('.vss-wrap').css('transform', 'translate3d('+ movemVal +'px, 0px, 0px)');

        }
    });
})(jQuery);
body {
  background: #222
}
.vs-slider {
  position: relative;
 /* overflow: hidden;*/    
  max-height: 290px;
  max-width: 500px;
  margin: auto;
}
.vs-slider img {
	margin: 0;
	vertical-align: top;
}
.vs-slider .vss-wrap {
	min-width: 90VW;
	transform: translate3d(0px, 0px, 0px);
	transition: all 0.5s ease 0s;
}
.vs-slider .vss-wrap::after {
    clear: both;
    width: 100%;
    display: block;
    content: "";
}

/* THIS WILL MAKE THE TRANSITION OVER CSS */

/*
This will throw all .item to the left at 50% relative to the container .vss-wrap
*/
.vs-slider .item {
  transform: translate3d(-50%, 0, 0) scale(.7);
  z-index: 1;
  position: absolute;
  opacity: .2;
  transition: all 1s;
  top: 0;
  z-index: 1;
}

/*
This will show and apply the transition only to the .active element
*/
.vs-slider .item.active {
  transform: translate3d(0, 0, 0) scale(1);
  opacity: 1;
  z-index: 2;
  position: relative;
}

/*
This will throw all elements set to the right of the .active element to 50% to the right and apply css styles
*/
.vs-slider .item.active ~ .item {
  transform: translate3d(50%, 0, 0) scale(.7);
}

/* THIS WILL MAKE THE TRANSITION OVER CSS */

.vss-nav {
    position: absolute;
    margin: 0;
    padding: 0;
    right: 5px;
    bottom: 0;
}
.vss-nav li {
    display: inline-block;
    color: #fff;
    margin: 0 5px;
    cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="vs-slider">
						<div class="vss-wrap">
							<div class="item active"><img src="https://i.guim.co.uk/img/media/59dee3fae368b6625fcd588cdc0c759f6aacd117/0_0_6100_3660/500.jpg?quality=85&auto=format&fit=max&s=998f324a337c7c17be1d754e3b856201" alt="Slider Item" width="430" height="280"></div>
							<div class="item"><img src="https://www.chileholidayarchitects.com/wp-content/uploads/2018/11/Chile-General-007-500x300.jpg" alt="Slider Item" width="430" height="280"></div>
							<div class="item"><img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTDYTOz0c9d1h4Xj4HULfGeZVrQMw3zzA77vEPuX-RMY6ah8GkY" alt="Slider Item" width="430" height="280"></div>
						</div>
						<ul class="vss-nav">
							<li class="prev">&lt;</li>
							<li class="next">&gt;</li>
						</ul>
					</div>
0 голосов
/ 12 января 2019

Вы можете сделать это просто по индексу. Я понятия не имею, почему вы использовали 299, так что рассматривая его как 100 x 3, где 100 - это оставленный ход 1.

См. Фрагмент ниже:

;( function($) {
    $(document).ready(function() {
        $('.vs-slider .item').each( function() {
            $(this).css('z-index', $('.vs-slider .item').length - $('.vs-slider .item').index(this));
        });

        $('.vss-nav').on('click', '.prev, .next', function() {
            var active = $(this).closest('.vs-slider').find('.item.active');
            var activeIndex = $('.vs-slider .item').index(active);
            
            var moveValue = 0;
            
            if ( $(this).hasClass('next') ) {
            	if(activeIndex+1== $('.vs-slider .item').length){
                moveValue = 0;
								$($('.vs-slider').find('.item').first()).addClass('active');
              }else{
              	moveValue = $('.vs-slider').find('.vss-wrap').position().left - ($('.vs-slider').find('.item').outerWidth() - 299);;
                active.next().addClass('active');
               ;
              }
            }else{
            	if(activeIndex-1 == -1){
              	moveValue = -($('.vs-slider .item').length * 100);
								$($('.vs-slider').find('.item').last()).addClass('active');
              }else{
              	moveValue =  $('.vs-slider').find('.vss-wrap').position().left + ($('.vs-slider').find('.item').outerWidth() - 299);
                active.prev().addClass('active');
              }            
            }
            $('.vs-slider').find('.vss-wrap').css('transform', 'translate3d('+ moveValue +'px, 0px, 0px)');
            active.removeClass('active');
        });
        
    });
})(jQuery);
body {
  background: #222
}
.vs-slider {
  position: relative;
  overflow: hidden;    
  max-height: 290px;
  max-width: 500px;
}
.vs-slider img {
	margin: 0;
	vertical-align: top;
}
.vs-slider .vss-wrap {
	min-width: 90VW;
	transform: translate3d(0px, 0px, 0px);
	transition: all 0.5s ease 0s;
}
.vs-slider .vss-wrap::after {
    clear: both;
    width: 100%;
    display: block;
    content: "";
}
.vs-slider .item {
	float: left;
	border: 1px solid #fff;
	transform: scale(.7);
	position: relative;
	z-index: 1;
	transition: all 1s ease 0s;
	margin-right: -299px;
}
.vs-slider .item.active {
	transform: scale(1);
	z-index: 20 !important;
}
.vs-slider .item:not(.active) {
    z-index: 0;
    cursor: pointer;
}
.vss-nav {
    position: absolute;
    margin: 0;
    padding: 0;
    right: 5px;
    bottom: 0;
}
.vss-nav li {
    display: inline-block;
    color: #fff;
    margin: 0 5px;
    cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="vs-slider">
						<div class="vss-wrap">
							<div class="item active"><img src="http://lorempixel.com/430/280/sports" alt="Slider Item" width="430" height="280"></div>
							<div class="item"><img src="http://lorempixel.com/430/280/animals" alt="Slider Item" width="430" height="280"></div>
							<div class="item"><img src="http://lorempixel.com/430/280/nature" alt="Slider Item" width="430" height="280"></div>
						</div>
						<ul class="vss-nav">
							<li class="prev">&lt;</li>
							<li class="next">&gt;</li>
						</ul>
					</div>

Вы также можете проверить это здесь

...