在document.body上使用scrollLeft进行水平滚动在Firefox / Safari中不起作用

时间:2019-06-24 13:15:02

标签: javascript mousewheel

我正在使用CSS网格构建水平滚动,并在触发(document.documentElement || document.body.parentNode || document.body)事件时更改mousewheel的offsetLeft。它在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 :(得分:0)

事件mousewheel在Firefox上不起作用,您需要将其替换为DOMMouseScroll,因此,需要检查用户是否使用的是Chrome或Firefox并基于设置的事件侦听器。或者,您可以像这样在init()上添加两个侦听器。

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