如果慢慢离开屏幕,Touchend iOS不会被解雇

时间:2016-02-22 11:03:09

标签: javascript ios javascript-events touch

我构建了一个处理touchstarttouchendtouchmove事件的Slider。

它适用于Android和iOS。 只有当我慢慢地在iOS上移动我的手指时,touchend事件才会被解雇。 在我将手指放回屏幕后,touchend事件将立即触发,但不是触摸开始。

有人知道为什么touchend事件会被解雇吗?

我搜索了几个小时才找到解决方案。 我试过了touchcancel,但它没有帮助。

的javascript:

this.element = document.createElement('div');
this.element.classList.add('slider');
parent.appendChild(this.element);
//other stuff

this.element.addEventListener('touchstart', ()=> {
    console.log('start');
});
this.element.addEventListener('touchend', ()=> {
    console.log('end');
});
this.element.addEventListener('touchmove', ()=> {
    console.log('move');
});

的CSS:

.slider{
      display: block;
      position: relative;
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
}

编辑#1

我也试过了gestureend,但它没有帮助。

我发现当我用家庭按钮滑到一边时,它才会被解雇(我处于横向模式)。

1 个答案:

答案 0 :(得分:0)

我在用打包在Cordova中的ios的Vue.js应用程序中构建滑块时遇到了完全相同的问题。

我没有找到导致touchend事件不会在ios设备的“按钮端”触发的行为的原因,但是我确实创建了一种解决方法。

我认为这与您不再相关,但是它可能会帮助有此问题的其他人:

我的事件的上下文(对于非Vue用户this.$refs.profileSlider只是对包裹我的滑块的元素的DOM引用):

  this.$refs.profileSlider.addEventListener('mousedown', this.lock, false);
  this.$refs.profileSlider.addEventListener('touchstart', this.lock, false);

  this.$refs.profileSlider.addEventListener('mousemove', this.drag, false);
  this.$refs.profileSlider.addEventListener('touchmove', this.drag, false);

  this.$refs.profileSlider.addEventListener('mouseup', this.move, false);
  this.$refs.profileSlider.addEventListener('touchend', this.move, false);

为了确保即使move()事件不触发(当用户从​​屏幕末端滑出时)也调用touchend函数,我在条件末尾添加了条件检查touchmove处理程序,这里称为drag

  // Rest of touchmove handler here
  const unified = this.unify(e);

  if (unified.clientX >= window.innerWidth - 3 || unified.clientX <= 3) {
    this.$refs.profileSlider.dispatchEvent(new TouchEvent('touchend', e));
  }
此功能中的

etouchmove事件的上下文。这样,drag()处理程序将正常运行,然后检查touchmove事件是否在屏幕任一侧的3px范围内发生(此灵敏度对我而言有效)。如果是这样,它将触发一个新的touchend TouchEvent并传递与先前的e相同的touchmove值。

这解决了touchend在用户的触摸持续超出屏幕边缘时不触发的问题。取而代之的是touchend被抢先触发,否则在滑动之前退出屏幕。

//作为参考,在上面的块中调用的unify函数只是检查事件中的changedTouches,并返回第一个changedTouch(如果存在):

unify(e) {
  return e.changedTouches ? e.changedTouches[0] : e;
}