Как сделать скролл по оси X внутри слайда в слайдере?

Есть слайдер, который работает на touchswipe.js
Внутри слайдов есть проскролливаемый по оси X блок. Как сделать, чтобы его можно было скроллить свайпом (если с мобильного) или колёсиком мыши (если с ПК)? Сейчас, если пытаюсь скроллить свайпом, прокручивается сам слайдер.

На codepen:


Разметка:

<section>
  <div class="product-slider">
    <div class="slider-box">
      <div class="slider">
        <div class="slide">
          <div class="image">
            <div class="main_img">
              <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_1.jpg" />
            </div>
            <div class="dop_imgs">
              <div class="dop_img">
                <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_1.jpg" />
              </div>
              <div class="dop_img">
                <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_2.jpg" />
              </div>
              <div class="dop_img">
                <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_3.jpg" />
              </div>
              <div class="dop_img">
                <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_4.jpg" />
              </div>
              <div class="dop_img">
                <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_5.jpg" />
              </div>
          </div>
        </div>
        </div>
        <div class="slide">
          <div class="image">
  <div class="main_img">
    <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_1.jpg" />
  </div>
  <div class="dop_imgs">
    <div class="dop_img">
      <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_1.jpg" />
    </div>
    <div class="dop_img">
      <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_2.jpg" />
    </div>
    <div class="dop_img">
      <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_3.jpg" />
    </div>
    <div class="dop_img">
      <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_4.jpg" />
    </div>
    <div class="dop_img">
      <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_5.jpg" />
    </div>
</div>
        </div>
        </div>
        <div class="slide">
          <div class="image">
  <div class="main_img">
    <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_1.jpg" />
  </div>
  <div class="dop_imgs">
    <div class="dop_img">
      <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_1.jpg" />
    </div>
    <div class="dop_img">
      <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_2.jpg" />
    </div>
    <div class="dop_img">
      <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_3.jpg" />
    </div>
    <div class="dop_img">
      <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_4.jpg" />
    </div>
    <div class="dop_img">
      <img src="https://murom-mebel-spb.ru/sites/default/files/styles/full_product/public/products/krovat_bali_layt_5.jpg" />
    </div>
</div>
        </div>
        </div>
      </div>
    </div>
  </div>
</section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.touchswipe/1.6.19/jquery.touchSwipe.min.js"></script>


CSS

section {
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: 360px;
}
.product-slider {
  display: flex;
  width: 100%
}
.slider-box {
  display: flex;
  max-width: 360px;
  height: 270px;
  overflow: hidden;
}
.slider {
  display: flex;
}
.slide {
  max-width: 360px;
}
.slide img {
  width: 360px;
  height: auto;
}
.image {
  display: flex;
  overflow-x: scroll;
}
.dop_imgs {
  display: flex;
}


JS

class Slider {
  constructor(slider) {
    this.currentImg = 0;
    this.speed = 500;
    
    this.swipeStatus = this.swipeStatus.bind(this);
    this.keyboardHandler = this.keyboardHandler.bind(this);
    this.scrollImages = this.scrollImages.bind(this);
    
    this.previousImage = this.previousImage.bind(this);
    this.nextImage = this.nextImage.bind(this);
    
    this.sliderWrapper = $(slider);
    this.slider = this.sliderWrapper.find('.slider');
    this.sliderBox = this.sliderWrapper.find('.slider-box');

    this.sliderWrapper
      .find('.slider-box')
      .attr("tabIndex", 0)
      .on("blur focus click", this.keyboardHandler)
      .swipe({
        triggerOnTouchEnd: true,
        triggerOnTouchLeave: true,
        swipeStatus: this.swipeStatus,
        allowPageScroll: "vertical",
        threshold: 75
      });
    this.maxImages = this.slider.find(">*").length;
    this.visibleImages = this.sliderBox.width() / this.slider.find(".slide").width();
    this.imagesOut = ( this.maxImages - this.sliderBox.width() / ( this.slider.find(".slide").width() ) );

    if ( 0 < this.imagesOut ) {
        this.sliderBox.append('<div class="slider-btn slider-previous-btn"></div><div class="slider-btn slider-next-btn"></div>');
    }

    this.prevBtn = this.sliderWrapper.find(".slider-previous-btn");
    this.nextBtn = this.sliderWrapper.find(".slider-next-btn");
    
    this.prevBtn.on("click", this.previousImage);
    this.nextBtn.on("click", this.nextImage);
  }
  keyboardHandler(event) {
      if (event.type === "focus") {
          document.addEventListener("keydown", this.keyboardHandler);
          this.constructor.activeInstance = this;
      } else if (event.type === "blur") {
          document.removeEventListener("keydown", this.keyboardHandler);
          this.constructor.activeInstance = null;
      } else if (event.type === "keydown") {
          if (event.keyCode === 37) this.previousImage();
          if (event.keyCode === 39) this.nextImage();
      } else {
          this.sliderBox.focus();
      }

      return true;
  }
  
  
  swipeStatus(event, phase, direction, distance) {
    //If we are moving before swipe, and we are going L or R in X mode, or U or D in Y mode then drag.
    if (phase == "move" && (direction == "left" || direction == "right")) {
      var duration = 0;
      if ( this.slider.hasClass( 'swiping' ) === false ) {
        this.slider.addClass( 'swiping' );
      }
      if (direction == "left") {
        this.scrollImages(
          this.currentImg + 0.0025 * distance, duration
        );
      } else if (direction == "right") {
        this.scrollImages(
          this.currentImg - 0.0025 * distance, duration
        );
      }
    } else if (phase == "cancel") {
      this.scrollImages(this.currentImg, this.speed);
    } else if (phase == "end") {
      if (direction == "right") {
        this.previousImage();
      } else if (direction == "left") {
        this.nextImage();
      }
    }
  }

  scrollImages(distance, duration) {
      this.slider.css("transition-duration", (duration / 1000).toFixed(1) + "s");
      this.slider.css("transform", "translate(" + (100 * -distance / this.maxImages) + "%,0)");
      $('.slider-box a').on('click', function (ea) {
        if( $('.slider').hasClass('swiping') ) {
          ea.preventDefault();
        } else {
          console.log('clicked');
        }
      });
  }

  previousImage() {
    if (this.currentImg != '0') {
        this.currentImg = Math.max(this.currentImg - 1, 0);
        this.scrollImages(this.currentImg, this.speed);
        if ( this.slider.hasClass( 'swiping' ) ) {
          setTimeout(function() {
            $('.slider.swiping').removeClass('swiping');
          }, 100 );
        }
    } else {
        this.currentImg = this.maxImages - 1;
        this.scrollImages(this.currentImg, this.speed);
        if ( this.slider.hasClass( 'swiping' ) ) {
          setTimeout(function() {
            $('.slider.swiping').removeClass('swiping');
          }, 100 );
        }
    }
  }

  nextImage() {
    if (this.currentImg != this.maxImages - 1) {
        this.currentImg = Math.min(this.currentImg + 1, this.maxImages - 1);
        this.scrollImages(this.currentImg, this.speed);
        if ( this.slider.hasClass( 'swiping' ) ) {
          setTimeout(function() {
            $('.slider.swiping').removeClass('swiping');
          }, 100 );
        }
    } else {
        this.currentImg = 0;
        this.scrollImages(this.currentImg, this.speed);
        if ( this.slider.hasClass( 'swiping' ) ) {
          setTimeout(function() {
            $('.slider.swiping').removeClass('swiping');
          }, 100 );
        }
    }
  }
}

$(() => {
  for (const element of $(".product-slider")) {
    new Slider(element);
  }
});

  • Вопрос задан
  • 160 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
SummerWeb Ярославль
от 120 000 до 180 000 ₽
Brightdata Тель-Авив
от 5 500 до 6 500 $
Market-place Ростов-на-Дону
от 100 000 до 200 000 ₽
21 июн. 2024, в 23:20
10000 руб./за проект
21 июн. 2024, в 23:14
600 руб./за проект
20 июн. 2024, в 17:08
3000 руб./в час