javascript - 如果缓慢离开屏幕,Touchend iOS 不会触发

标签 javascript ios touch dom-events

我构建了一个处理 touchstart 的 slider , touchendtouchmove事件。

它在 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但这无济于事。

我发现只有当我用主页按钮滑动到一侧时它才不会触发(我处于横向模式)。

最佳答案

在使用 Cordova 包装的 Vue.js 应用程序中为 ios 构建 slider 时,我遇到了完全相同的问题。

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

我假设这与您不再相关,但它可能会帮助遇到此问题的其他人:

我的事件上下文(对于非 Vue 用户 this.$refs.profileSlider 只是对包裹我的 slider 的元素的 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));
  }
e在这个函数中是 touchmove 的上下文事件。这样 drag()处理程序将正常运行,然后检查 touchmove事件发生在屏幕任一侧的 3px 内(此灵敏度适用于我的目的)。如果是这样,它会触发一个新的 touchend TouchEvent并通过相同的e值与之前的 touchmove 相同.

这解决了 touchend 的问题当用户的触摸继续离开屏幕边缘时不会触发。而是 touchend被抢先触发,就在滑动将退出屏幕之前。

//作为引用,unify在上面的 block 中调用的函数只是检查 changedTouches事件,并返回第一个 changedTouch如果存在:
unify(e) {
  return e.changedTouches ? e.changedTouches[0] : e;
}

关于javascript - 如果缓慢离开屏幕,Touchend iOS 不会触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35551948/

相关文章:

ios - 带有 block 的 UIView 动画是如何工作的

ios - 多个 View 处理的触摸事件

javascript - 防止 firefox 在溢出元素更改时重置滚动位置

javascript - 卡在 else if 循环中

ios - 设置UIToolBar背景图片

html - 触摸点击html元素下的按钮

javascript - 每 x 毫秒获取 jquery 触摸位置

Javascript 模块模式事件和监听器

javascript - JS平均计算器

ios - 调用了 awakeFromNib,未调用 viewDidLoad