鼠标&触摸水平div滑动

时间:2016-10-07 12:33:32

标签: javascript jquery touch mouseevent

我正在尝试为我的网站制作一个功能,允许用户使用mousemove和touchmove事件水平滚动div内容(它类似于Apple AppStore any app Screenshots section)。我这样做是为第一个孩子设置一个负余量左边的属性。一切正常,除了当移动设备上的用户触摸屏幕或桌面上的光标移动到父div时,它的内容不是从当前的位置滚动而是“跳跃”。我尝试通过将当前margin-left值添加到新的pageX值来实现此目的,但它不起作用。我做错了什么?或者也许不可能这样做这个功能?

JS / Babel代码:

<form class="form-horizontal">
<fieldset>
<!-- Text input-->
        <div class="form-group">
            <label for="dtp_input1" class="col-md-2 control-label">FROM:   </label>
            <div class="input-group date form_date col-md-5" data-date="" data-date-format="dd MM yyyy" data-link-field="dtp_input1" data-link-format="yyyy-mm-dd">
                <input class="form-control" size="16" type="text" value="" readonly>
                <span class="input-group-addon"><span class="glyphicon glyphicon-remove"></span></span>
                <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
            </div>
            <input type="hidden" id="dtp_input1" value="" /><br/>
        </div>
        <div class="form-group">
            <label for="dtp_input2" class="col-md-2 control-label">TO:</label>
            <div class="input-group date form_date col-md-5" data-date="" data-date-format="dd MM yyyy" data-link-field="dtp_input2" data-link-format="yyyy-mm-dd">
                <input class="form-control" size="16" type="text" value="" readonly>
                <span class="input-group-addon"><span class="glyphicon glyphicon-remove"></span></span>
                <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
            </div>
            <input type="hidden" id="dtp_input2" value="" /><br/>
        </div>

  <!-- Text input-->

<!-- Button -->
<div class="form-group">
<div class="col-md-8 text-right">
<input type="submit" class="btn btn-warning" formaction="dates.php" formmethod="POST"></button>
 </div>
 </div></fieldset>
 </form>

SCSS代码:

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

我的fiddle

提前感谢您的回答。

2 个答案:

答案 0 :(得分:1)

你可以在没有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 */
}

答案 1 :(得分:0)

我处理这个问题。通过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