同步方向控制和滑动事件

12
我已经建立了两种控制幻灯片的功能。一种是带有方向控制的按钮,另一种是触摸/滑动事件。如何将它们同步,以便当我按下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>

1个回答

4

您在这里存在多个问题:

  1. 您使用了两种不同的方法来定位幻灯片(您使用的hammer插件使用translateX进行定位,而您尝试使用css right进行定位)。
  2. 每种方法都使用不同的源来确定哪个幻灯片是活动幻灯片(您使用.slider-wrapperattr,而hammer使用activeSlide变量)。

我修复了两个问题,使用translateX解决了它们,将activeSlide变量移出了$('.slider-wrapper .slider').each函数的作用域,并确保每个更改都会影响两个变量。

请注意,我们可以删除其中一个变量并仅使用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>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接