Как исправить мобильный поэкранный скроллинг?

Есть скрипт на vue, который создает скролл экранами. Для body соответственно ставится overflow: hidden. А для секций .sections устанавливается height: 100hv.

Разметка HTML

<div class="sections_wrap">
  <div class="sections">1</div>
  <div class="sections">2</div>
  <div class="sections">3</div>
  <div class="sections">4</div>
  <div class="sections">5</div>
</div>



Код скрипта
var app = new Vue({
  el: '.sections_wrap',
  data: {
    inMove: false,
    activeSection: 1,
    offsets: [],
    touchStartY: 0
  },
  methods: {
    calculateSectionOffsets() {
      let sections = document.getElementsByClassName('sections');
      let length = sections.length;

      for(let i = 0; i < length; i++) {
        let sectionOffset = sections[i].offsetTop;
        this.offsets.push(sectionOffset);
      }
    },
    handleMouseWheel: function(e) {

      if (e.wheelDelta < 30 && !this.inMove) {
        this.moveUp();
      } else if (e.wheelDelta > 30 && !this.inMove) {
        this.moveDown();
      }

      e.preventDefault();
      return false;
    },
    handleMouseWheelDOM: function(e) {

      if (e.detail > 0 && !this.inMove) {
        this.moveUp();
      } else if (e.detail < 0 && !this.inMove) {
        this.moveDown();
      }

      return false;
    },
    moveDown() {
      this.inMove = true;
      this.activeSection--;

      if(this.activeSection < 0) this.activeSection = this.offsets.length - 1;

      this.scrollToSection(this.activeSection, true);
    },
    moveUp() {
      this.inMove = true;
      this.activeSection++;

      if(this.activeSection > this.offsets.length - 1) this.activeSection = 1;

      this.scrollToSection(this.activeSection, true);
    },
    scrollToSection(id, force = false) {
      if(this.inMove && !force) return false;

      this.activeSection = id;
      this.inMove = true;

      document.getElementsByTagName('section')[id].scrollIntoView({behavior: 'smooth'});

      setTimeout(() => {
        this.inMove = false;
      }, 400);

    },
//////////////////////////////////
//////////////////////////////////
//////////////////////////////////
// обработка тачей
//////////////////////////////////
//////////////////////////////////
//////////////////////////////////
    touchStart(e) {
      e.preventDefault();

      this.touchStartY = e.touches[0].clientY;
    },
    touchMove(e) {
      if(this.inMove) return false;
      e.preventDefault();

      const currentY = e.touches[0].clientY;

      if(this.touchStartY < currentY) {
        this.moveDown();
      } else {
        this.moveUp();
      }

      this.touchStartY = 0;
      return false;
    }
  },
  created() {
    this.calculateSectionOffsets();

    window.addEventListener('DOMMouseScroll', this.handleMouseWheelDOM);  // Mozilla Firefox
    window.addEventListener('mousewheel', this.handleMouseWheel, { passive: false }); // Other browsers

    window.addEventListener('touchstart', this.touchStart, { passive: false }); // mobile devices
    window.addEventListener('touchmove', this.touchMove, { passive: false }); // mobile devices
  },
  destroyed() {
    window.removeEventListener('mousewheel', this.handleMouseWheel, { passive: false });  // Other browsers
    window.removeEventListener('DOMMouseScroll', this.handleMouseWheelDOM); // Mozilla Firefox

    window.removeEventListener('touchstart', this.touchStart); // mobile devices
    window.removeEventListener('touchmove', this.touchMove); // mobile devices
  }
});


На ПК все работает отлично, однако на touch-устройствах есть проблема: листинг экрана вниз или вверх срабатывает при любом касании экрана. Можно ли изменить логику так, чтобы следующий экран показывался только при свайпе вверх, а предыдущий — только при свайпе вниз?
  • Вопрос задан
  • 96 просмотров
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы