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

Синхронизировать направленные элементы управления с помощью событий салфетки

Я создал две функции для управления ползунком, который я создал. Один из них - кнопки с направленными элементами управления, а другие - события касания/салфетки. Как синхронизировать оба из них так, чтобы, когда я нажимаю prev/next, события салфетки также обновляются и наоборот

$(document).ready(function() {


	$('.prev').on('click', function(e) {
	    event.stopPropagation();
	    // store variable relevent to clicked slider
	    var sliderWrapper      = $(this).closest('.slider-wrapper'),
		    slideItems         = sliderWrapper.find('.slide-items'),
	        slider             = sliderWrapper.find('.slider'),
	        currentSlide       = sliderWrapper.attr('data-slide');

	    // Check if data-slide attribute is greater than 0
	    if( currentSlide > 0 ) {
			// Decremement current slide
			currentSlide--;
			// Assign CSS position to clicked slider
			slider.css({'right' : currentSlide*slideItems.outerWidth() });
			// Update data-slide attribute
			sliderWrapper.attr('data-slide', currentSlide);
	    }
	});

	$('.next').on('click', function(e) {
	    event.stopPropagation();
	    // store variable relevent to clicked slider

		var sliderWrapper      = $(this).closest('.slider-wrapper'),
		    slideItems         = sliderWrapper.find('.slide-items'),
		    slider             = sliderWrapper.find('.slider'),
		    totalSlides        = slideItems.length,
		    currentSlide       = sliderWrapper.attr('data-slide');

		// Check if dataslide is less than the total slides
		if( currentSlide < totalSlides - 1 ) {
		    // Increment current slide
		    currentSlide++;
		    // Assign CSS position to clicked slider
		    slider.css({'right' : currentSlide*slideItems.outerWidth() });
		    // Update data-slide attribute
		    sliderWrapper.attr('data-slide', currentSlide);
		}
	})

	$('.slider-wrapper .slider').each(function(){

	    // create a simple instance
	    // by default, it only adds horizontal recognizers
	 
	    var direction;
        var touchSlider = this;
        var activeSlide = 0;
	    var mc = new Hammer.Manager(this),
	        itemLength = $(this).find('.slide-items').length,
	        count = 0,
	        slide = $(this);
	    
		var sliderWrapper      = slide,
		    slideItems         = sliderWrapper.find('.slide-items'),
		    slider             = sliderWrapper.find('.slider'),
		    totalSlides        = slideItems.length,
		    currentSlide       = sliderWrapper.attr('data-slide');
	    
	    // mc.on("panleft panright", function(ev) {
	    //   direction = ev.type;
	    // });
        
        mc.add(new Hammer.Pan({ threshold: 0, pointers: 0 }))
	    mc.on('pan', function(e) {	
            var percentage = 100 / totalSlides * e.deltaX / window.innerWidth;
            var transformPercentage = percentage - 100 / totalSlides * activeSlide;
            touchSlider.style.transform = 'translateX( ' +  transformPercentage + '% )';

			if( e.isFinal ) { // NEW: this only runs on event end
			    if( percentage < 0 )
			        goToSlide( activeSlide + 1 );
			    else if( percentage > 0 )
			        goToSlide( activeSlide - 1 );
			    else
			        goToSlide( activeSlide );
			}


	    });


		var goToSlide = function( number ) {
		  if( number < 0 )
		    activeSlide = 0;
		  else if( number > totalSlides - 1 )
		    activeSlide = totalSlides - 1
		  else
		    activeSlide = number;

		  touchSlider.classList.add('slide-animation');
		  var percentage = -( 100 / totalSlides ) * activeSlide;
		  touchSlider.style.transform = 'translateX( ' + percentage + '% )';
		  timer = setTimeout( function() {
		      touchSlider.classList.remove('slide-animation');
		  }, 400);

		};

	   //  mc.on("panend", function(ev) {
		  //   if(direction === "panleft") {
	   //          console.log('panleft');

				// // Check if dataslide is less than the total slides
				// if( currentSlide < totalSlides - 1 ) {
				//     // Increment current slide
				//     currentSlide++;
				//     // Assign CSS position to clicked slider
				//     slider.css({'right' : currentSlide*slideItems.outerWidth() });
				//     // Update data-slide attribute
				//     sliderWrapper.attr('data-slide', currentSlide);
				// }
		  //   }

		  //   if(direction === "panright") {
	   //          console.log('right');

			 //    // Check if data-slide attribute is greater than 0
			 //    if( currentSlide > 0 ) {
				// 	// Decremement current slide
				// 	currentSlide--;
				// 	// Assign CSS position to clicked slider
				// 	slider.css({'right' : currentSlide*slideItems.outerWidth() });
				// 	// Update data-slide attribute
				// 	sliderWrapper.attr('data-slide', currentSlide);
			 //    }
		  //   }
	   //  });
	});

});




$(window).on('load', function() {
  $('.slider-wrapper').each(function() {
    var slideItems = $(this).find('.slide-items'),
    items = slideItems.length,
    sliderBox = $(this).find('.slider'),
    sliderWrapperWidth = $(this).width();
    
    slideItems.outerWidth( sliderWrapperWidth );
    
    sliderBox.width( slideItems.outerWidth() * items  );
  });

});
/* http://meyerweb.com/eric/tools/css/reset/
 v2.0 | 20110126
 License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline; }

/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
  display: block; }

body {
  line-height: 1; }

ol, ul {
  list-style: none; }

blockquote, q {
  quotes: none; }

blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none; }

table {
  border-collapse: collapse;
  border-spacing: 0; }

* {
  box-sizing: border-box; }

.container {
  max-width: 1280px;
  margin: 0 auto; }

.container .slider-wrapper {
  margin-bottom: 40px;
  background-color: grey;
  overflow: hidden;
  display: block; }

.container .slider-wrapper .slider {
  position: relative;
  right: 0;
  display: flex;
  flex-wrap: wrap;
  overflow: hidden;
  /*-webkit-transition : transform 0.3s linear;*/ }
  .container .slider-wrapper .slider.slide-animation {
    -webkit-transition: transform 0.3s linear; }

.container .slider-wrapper .slider > div {
  padding: 10px;
  background-color: #e5d0d0;
  height: 200px; }

.container .slider-wrapper .slider > div p {
  color: purple; }

.container .slider-wrapper .buttons {
  display: flex;
  justify-content: space-between;
  background: beige;
  padding: 10px 0; }

.container .slider-wrapper .buttons div {
  background-color: cyan; }

/*# sourceMappingURL=style.css.map */
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.7/hammer.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="slider-wrapper" data-slide="0">
    <div class="slider">
        <div class="slide-items">
            <p>1</p>
        </div>

        <div class="slide-items">
            <p>2</p>
        </div>

        <div class="slide-items">
            <p>3</p>
        </div>
    </div>
    <div class="buttons">
        <div class="prev">prev</div>
        <div class="next">next</div>
    </div>
  </div>
  <div class="slider-wrapper" data-slide="0">
    <div class="slider">
        <div class="slide-items">
            <p>1</p>
        </div>
    </div>
    <div class="buttons">
        <div class="prev">prev</div>
        <div class="next">next</div>
    </div>
  </div>

  <div class="slider-wrapper" data-slide="0">
    <div class="slider">
        <div class="slide-items">
            <p>2</p>
        </div>
        <div class="slide-items">
            <p>3</p>
        </div>
    </div>
    <div class="buttons">
        <div class="prev">prev</div>
        <div class="next">next</div>
    </div>
  </div>
  <div class="slider-wrapper" data-slide="0">
    <div class="slider">
        <div class="slide-items">
            <p>1</p>
        </div>
    </div>
    <div class="buttons">
        <div class="prev">prev</div>
        <div class="next">next</div>
    </div>
  </div>
  <div class="slider-wrapper" data-slide="0">
    <div class="slider">
        <div class="slide-items">
            <p>1</p>
        </div>

        <div class="slide-items">
            <p>2</p>
        </div>
    </div>
    <div class="buttons">
        <div class="prev">prev</div>
        <div class="next">next</div>
    </div>
  </div>
</div>
4b9b3361

Ответ 1

У вас было несколько проблем:

  • Вы использовали два разных подхода для размещения слайда (плагин hammer, который вы использовали, позиционировал его с помощью translateX, в то время как вы пытались позиционировать с помощью css right.
  • Каждый метод использовал другой источник, чтобы определить, какой слайд является активным (вы использовали attr для .slider-wrapper, а hammer использовали переменную activeSlide.

Я исправил как использование translateX, так и перемещал переменную activeSlide за пределы области $('.slider-wrapper .slider').each и следил за тем, чтобы каждое изменение повлияло на обе переменные.

Node, что мы можем удалить одну из переменных и использовать только значение attr, но я оставлю это для вас:)

Вот рабочий фрагмент:

$(document).ready(function() {

    var activeSlide = 0;

    $('.prev').on('click', function(e) {
        event.stopPropagation();
        // store variable relevent to clicked slider
        var sliderWrapper = $(this).closest('.slider-wrapper'),
            slideItems = sliderWrapper.find('.slide-items'),
            totalSlides = slideItems.length,
            slider = sliderWrapper.find('.slider'),
            currentSlide = parseInt(sliderWrapper.attr('data-slide'));

        // Check if data-slide attribute is greater than 0
        if (currentSlide > 0) {
            // Decremement current slide
            currentSlide--;
            // Assign CSS position to clicked slider
            var transformPercentage = -1 * currentSlide / totalSlides * 100;
            slider.css('transform', 'translateX(' + transformPercentage + '% )');
            // Update data-slide attribute
            sliderWrapper.attr('data-slide', currentSlide);
            activeSlide = currentSlide;
        }
    });

    $('.next').on('click', function(e) {
        event.stopPropagation();
        // store variable relevent to clicked slider

        var sliderWrapper = $(this).closest('.slider-wrapper'),
            slideItems = sliderWrapper.find('.slide-items'),
            slider = sliderWrapper.find('.slider'),
            totalSlides = slideItems.length,
            currentSlide = parseInt(sliderWrapper.attr('data-slide'));

        // Check if dataslide is less than the total slides
        if (currentSlide < totalSlides - 1) {
            // Increment current slide
            currentSlide++;
            // Assign CSS position to clicked slider
            var transformPercentage = -1 * currentSlide / totalSlides * 100;
            slider.css('transform', 'translateX(' + transformPercentage + '% )');
            // Update data-slide attribute
            sliderWrapper.attr('data-slide', currentSlide);
            activeSlide = currentSlide;
        }
    })

    $('.slider-wrapper .slider').each(function() {

        // create a simple instance
        // by default, it only adds horizontal recognizers

        var direction;
        var touchSlider = this;
        var mc = new Hammer.Manager(this),
            itemLength = $(this).find('.slide-items').length,
            count = 0,
            slide = $(this);

        var sliderWrapper = slide,
            slideItems = sliderWrapper.find('.slide-items'),
            slider = sliderWrapper.find('.slider'),
            totalSlides = slideItems.length,
            currentSlide = parseInt(sliderWrapper.attr('data-slide'));

        // mc.on("panleft panright", function(ev) {
        //   direction = ev.type;
        // });

        mc.add(new Hammer.Pan({
            threshold: 0,
            pointers: 0
        }))
        mc.on('pan', function(e) {
            var percentage = 100 / totalSlides * e.deltaX / window.innerWidth;
            var transformPercentage = percentage - 100 / totalSlides * activeSlide;
            touchSlider.style.transform = 'translateX( ' + transformPercentage + '% )';
            var sliderWrapper = $(e.target).closest('.slider-wrapper')


            if (e.isFinal) { // NEW: this only runs on event end

                var newSlide = activeSlide;
                if (percentage < 0)
                    newSlide = activeSlide + 1;
                else if (percentage > 0)
                    newSlide = activeSlide - 1;
                goToSlide(newSlide, sliderWrapper);
            }
        });


        var goToSlide = function(number, sliderWrapper) {
            if (number < 0)
                activeSlide = 0;
            else if (number > totalSlides - 1)
                activeSlide = totalSlides - 1
            else
                activeSlide = number;

            sliderWrapper.attr('data-slide', activeSlide);

            touchSlider.classList.add('slide-animation');
            var percentage = -(100 / totalSlides) * activeSlide;
            touchSlider.style.transform = 'translateX( ' + percentage + '% )';
            timer = setTimeout(function() {
                touchSlider.classList.remove('slide-animation');
            }, 400);

        };

    });

});




$(window).on('load', function() {
    $('.slider-wrapper').each(function() {
        var slideItems = $(this).find('.slide-items'),
            items = slideItems.length,
            sliderBox = $(this).find('.slider'),
            sliderWrapperWidth = $(this).width();

        slideItems.outerWidth(sliderWrapperWidth);

        sliderBox.width(slideItems.outerWidth() * items);
    });

});
/* http://meyerweb.com/eric/tools/css/reset/
 v2.0 | 20110126
 License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline; }

/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
  display: block; }

body {
  line-height: 1; }

ol, ul {
  list-style: none; }

blockquote, q {
  quotes: none; }

blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none; }

table {
  border-collapse: collapse;
  border-spacing: 0; }

* {
  box-sizing: border-box; }

.container {
  max-width: 1280px;
  margin: 0 auto; }

.container .slider-wrapper {
  margin-bottom: 40px;
  background-color: grey;
  overflow: hidden;
  display: block; }

.container .slider-wrapper .slider {
  position: relative;
  right: 0;
  display: flex;
  flex-wrap: wrap;
  overflow: hidden;
  /*-webkit-transition : transform 0.3s linear;*/ }
  .container .slider-wrapper .slider.slide-animation {
    -webkit-transition: transform 0.3s linear; }

.container .slider-wrapper .slider > div {
  padding: 10px;
  background-color: #e5d0d0;
  height: 200px; }

.container .slider-wrapper .slider > div p {
  color: purple; }

.container .slider-wrapper .buttons {
  display: flex;
  justify-content: space-between;
  background: beige;
  padding: 10px 0; }

.container .slider-wrapper .buttons div {
  background-color: cyan; }

/*# sourceMappingURL=style.css.map */
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.7/hammer.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
    <div class="slider-wrapper" data-slide="0">
        <div class="slider">
            <div class="slide-items">
                <p>1</p>
            </div>

            <div class="slide-items">
                <p>2</p>
            </div>

            <div class="slide-items">
                <p>3</p>
            </div>
        </div>
        <div class="buttons">
            <div class="prev">prev</div>
            <div class="next">next</div>
        </div>
    </div>
    <div class="slider-wrapper" data-slide="0">
        <div class="slider">
            <div class="slide-items">
                <p>1</p>
            </div>
        </div>
        <div class="buttons">
            <div class="prev">prev</div>
            <div class="next">next</div>
        </div>
    </div>

    <div class="slider-wrapper" data-slide="0">
        <div class="slider">
            <div class="slide-items">
                <p>2</p>
            </div>
            <div class="slide-items">
                <p>3</p>
            </div>
        </div>
        <div class="buttons">
            <div class="prev">prev</div>
            <div class="next">next</div>
        </div>
    </div>
    <div class="slider-wrapper" data-slide="0">
        <div class="slider">
            <div class="slide-items">
                <p>1</p>
            </div>
        </div>
        <div class="buttons">
            <div class="prev">prev</div>
            <div class="next">next</div>
        </div>
    </div>
    <div class="slider-wrapper" data-slide="0">
        <div class="slider">
            <div class="slide-items">
                <p>1</p>
            </div>

            <div class="slide-items">
                <p>2</p>
            </div>
        </div>
        <div class="buttons">
            <div class="prev">prev</div>
            <div class="next">next</div>
        </div>
    </div>
</div>