Горизонтальная прокрутка с использованием scrollLeft на document.body не работает в Firefox / Safari - PullRequest
0 голосов
/ 24 июня 2019

Я строю горизонтальную прокрутку с сеткой CSS и меняю offsetLeft на (document.documentElement || document.body.parentNode || document.body), когда запускаю событие mousewheel. Он отлично работает в Chrome, но не в Firefox или Safari. Вот ручка, которую я создал, чтобы воспроизвести проблему: https://codepen.io/rluijten/pen/ewRpyM

class HorizontalScroll {
  constructor() {
    this.scrollContainer = document.querySelector('.js-scroll');
    this.target = (document.documentElement || document.body.parentNode || document.body);

    this.state = {
      moving: false,
      scrollDir: '',
      scrollPos: this.target.scrollLeft,
      scrollTop: 0,
      speed: 90,
      smooth: 12
    };

    this.rAF = null;
    
    this.scroll = this.scroll.bind(this);
    this.updateScrollPosition = this.updateScrollPosition.bind(this);
  }

  scroll(e) {
    e.preventDefault();

    // update scroll direction
    if (this.state.scrollPos > this.state.scrollTop) this.state.scrollDir = 'down';
    else this.state.scrollDir = 'up';

    this.state.scrollTop = this.state.scrollPos <= 0 ? 0 : this.state.scrollPos;
    
    console.log(this.target.scrollLeft);

    // smooth scroll
    let delta;
    if (e.detail) {
      if (e.wheelDelta) delta = e.wheelDelta / e.detail / 40 * (e.detail > 0 ? 1 : -1);
      else delta = -e.detail / 3;
    } else {
      delta = e.wheelDelta / 120;
    }

    this.state.scrollPos += -delta * this.state.speed;
    this.state.scrollPos = Math.max(
      0,
      Math.min(this.state.scrollPos, this.target.scrollWidth - this.target.clientWidth)
    );
    
    if (!this.state.moving) this.updateScrollPosition();
  }

  updateScrollPosition() {
    this.state.moving = true;

    const delta = (this.state.scrollPos - this.target.scrollLeft) / this.state.smooth;
    
    console.log(delta);

    this.target.scrollLeft += delta;

    if (Math.abs(delta) > 0) window.requestAnimationFrame(this.updateScrollPosition);
    else this.state.moving = false;
  }

  init() {
    window.addEventListener('mousewheel', this.scroll, { passive: false });
    console.log(this.target);
  }
}

const horizontalScroll = new HorizontalScroll();
horizontalScroll.init();
body {
  margin: 0;
}

.scroll {
  display: flex;
  align-items: center;
  height: 100vh;
}

.scroll__container {
  display: grid;
  grid-template-rows: repeat(2, 1fr);
  grid-row-gap: 15px;
  grid-auto-flow: column;
}

.scroll__content {
  display: flex;
  align-items: flex-end;
}

.scroll__element {
  display: inline-block;
  position: relative;
  margin-right: 15px;
}

.scroll__image {
  width: 400px;
  height: 200px;
  object-fit: cover;
}
<div class="scroll js-scroll">
  <div class="scroll__container js-filter-container">
    <div class="scroll__content js-content">
      <a href="#" class="scroll__element js-element">
        <img class="img scroll__image" src="https://source.unsplash.com/random" />
      </a>
      <a href="#" class="scroll__element js-element">
        <img class="img scroll__image" src="https://source.unsplash.com/random" />
      </a>
      <a href="#" class="scroll__element js-element">
        <img class="img scroll__image" src="https://source.unsplash.com/random" />
      </a>
      <a href="#" class="scroll__element js-element">
        <img class="img scroll__image" src="https://source.unsplash.com/random" />
      </a>
      <a href="#" class="scroll__element js-element">
        <img class="img scroll__image" src="https://source.unsplash.com/random" />
      </a>
      <a href="#" class="scroll__element js-element">
        <img class="img scroll__image" src="https://source.unsplash.com/random" />
      </a>
      <a href="#" class="scroll__element js-element">
        <img class="img scroll__image" src="https://source.unsplash.com/random" />
      </a>
    </div>
    <div class="scroll__content js-content">
      <a href="#" class="scroll__element js-element">
        <img class="img scroll__image" src="https://source.unsplash.com/random" />
      </a>
      <a href="#" class="scroll__element js-element">
        <img class="img scroll__image" src="https://source.unsplash.com/random" />
      </a>
      <a href="#" class="scroll__element js-element">
        <img class="img scroll__image" src="https://source.unsplash.com/random" />
      </a>
      <a href="#" class="scroll__element js-element">
        <img class="img scroll__image" src="https://source.unsplash.com/random" />
      </a>
      <a href="#" class="scroll__element js-element">
        <img class="img scroll__image" src="https://source.unsplash.com/random" />
      </a>
      <a href="#" class="scroll__element js-element">
        <img class="img scroll__image" src="https://source.unsplash.com/random" />
      </a>
      <a href="#" class="scroll__element js-element">
        <img class="img scroll__image" src="https://source.unsplash.com/random" />
      </a>
    </div>
  </div>
</div>

Есть идеи?

1 Ответ

0 голосов
/ 24 июня 2019

Событие mousewheel не работает в Firefox, вам необходимо заменить его на DOMMouseScroll, поэтому для этого вам нужно проверить, использует ли пользователь Chrome или Firefox и на основе этого набора прослушивателей событий. Или вы можете добавить обоих слушателей в свой init () следующим образом.

// Chrome
 window.addEventListener('mousewheel', this.scroll, { passive: false });
 // Firefox
 window.addEventListener("DOMMouseScroll", this.scroll, { passive: false });
...