鼠标和触摸水平 div 滑动

Mouse & Touch horizontal div sliding

我正在尝试为我的网站制作一项功能,允许用户使用 mousemove 和 touchmove 事件水平滚动 div 内容(类似于 Apple AppStore any app Screenshots section)。我通过为第一个 child 设置负 margin-left 属性 来做到这一点。一切正常,除了当移动设备上的用户触摸屏幕或桌面上的用户将光标移动到 parent div 时,它的内容不会从当前位置滚动,而是 "jumping"。我试图通过将当前 margin-left 值添加到新的 pageX 值来实现这一点,但它不起作用。我做错了什么?或者可能无法通过这种方式实现此功能?

JS/Babel代码:

class Collage {
  constructor(selector) {
    this.selector = $(selector);
    this.children = this.selector.children(':first-child');
    this.selector.on('mousemove touchmove', this.onMove.bind(this));
  }

  onMove(event) {
    const marginLeft = parseFloat(this.children.css('margin-left'));
    let mouseX = event.pageX || -event.touches[0].pageX || -event.changedTouches[0].pageX;

    const margin = calculateMargin(mouseX, 1);
    this.children.css('margin-left', margin);

    function calculateMargin(value, speed) {
      let val = -value*speed;
      return val <= 0 ? val : 0;
    }
  }
}

SCSS代码:

.collage {
  overflow: hidden;
  max-height: 300px;

  white-space: nowrap;

  font-size: 0;

  img {
    display: inline-block;
    &:first-of-type {
      margin-left: -20%;
    }
  }
}

我的fiddle

提前感谢您的回答。

您可以通过在图像周围创建第二个包装器元素来在没有 Javascript 的情况下获得您想要的内容吗?

<div class="collage">
  <div class="wrapper">
    <img /> ....
 </div>
</div>

然后CSS

.collage {
  overflow-x: scroll;
  -webkit-overflow-scrolling: touch;
  width: 100%;
  display: block;
  position: relative;
}
.wrapper {
   width: 10000px; 
  /* set width to something large 
     or set with Javascript to the calculated width of your images */
}

我处理这个问题。通过 Matthew Levy's 的回答,我发现它可以更容易地完成。所以我将全部内容放入嵌套容器中,我的 CSS (SCSS) 代码如下所示:

.collage {
  overflow: hidden;
  -webkit-overflow-scrolling: touch;

  width: 100%;
  max-height: 300px;

  font-size: 0;  

  .wrapper {
    width: 100%;
    height: 100%;
    overflow: auto;
    padding: 0;
    white-space: nowrap;
  }

  img {
    display: inline-block;
    &:first-of-type {
      // transition prevent jumping when user move cursor into container
      transition: margin .8s;
    }
  }
}

使用此代码,我不需要 JS 中的 touchmove 事件。所以现在我的 JS 代码如下所示(顺便说一句,我针对最后一个代码优化了这段代码):

class Collage {
  constructor(selector) {
    this.selector = $(selector);
    this.child = this.selector.children();

    const offsetHeight = this.child[0].offsetHeight;
    const clientHeight = this.child[0].clientHeight;
    // hide scrollbar - it can be done with CSS but in various browsers scrollbar may has various size so using JS to deal with this is safier
    this.selector.css('margin-top', -(offsetHeight - clientHeight));
    this.child.css('margin-top', offsetHeight - clientHeight);

    this.child.on('mousemove', this.onMove.bind(this));

    this.mouseX = 0;
    this.marginLeft = 0;

    this.selectorWidth = this.selector.width();
    this.selectorLeft = this.selector.position().left;
  }

  onMove(event) {
    // calculate new margin value in percentages
    const calculateMargin = () => parseInt((100 * (this.mouseX - this.selectorLeft)) / this.selectorWidth);

    this.mouseX = event.pageX;
    // limit a new value between 0/100%
    this.marginLeft += (Math.min(Math.max(calculateMargin(), 0), 100) - this.marginLeft);
    this.child.children(':first-child').css('margin-left', `-${this.marginLeft}%`);
  }
}

工作fiddle