M
M
mirti de vednis2020-10-05 13:33:11
JavaScript
mirti de vednis, 2020-10-05 13:33:11

How to fix mobile screen scrolling?

There is a vue script that creates scroll screens. The body is set to overflow: hidden accordingly. And .sections are set to height: 100hv.

HTML markup

<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>



Script code
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
  }
});


On PC everything works fine, but on touch devices there is a problem: listing the screen down or up is triggered by any touch on the screen. Is it possible to change the logic so that the next screen is shown only when swiping up, and the previous screen is only shown when swiping down?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question