Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS使用fastclick的情况下,下拉刷新会触发点击事件 #27

Open
Mywifi opened this issue Mar 15, 2017 · 10 comments
Open

iOS使用fastclick的情况下,下拉刷新会触发点击事件 #27

Mywifi opened this issue Mar 15, 2017 · 10 comments

Comments

@Mywifi
Copy link

Mywifi commented Mar 15, 2017

在iOS平台使用fastclick来解决延迟问题,但是在下拉刷新、上拉加载下一页,都会触发列表项目的点击事件,导致进入详情页了,这个如何解决?

@uncleLian
Copy link

在mint-ui源码 找到loadmore 相关代码 ,在handleTouchEnd 里面加上event.preventDefault();
event.stopPropagation(); 可以解决这个问题

@victorylin
Copy link

victorylin commented May 11, 2017

使用loadmore组件时,手势横向滑屏,稍微倾斜就会触发下拉更新。如何控制手势的方向,让用户只有比较明显的下拉手势时,才触发下拉更新。请帮忙解答一下,谢谢。

@uncleLian
Copy link

踩过坑的我,就帮忙解答一下吧。需要修改源码,方法1:在mint-ui.common.js找到loadmore组件相关代码,在handleTouchMove方法里 (2894行)把distance > 0 ? 'down' : 'up' 数值更改。 方法2:如果同时有上下左右的滑动,建议在源码增加一个属性,用于左右滑动(我左右滑动用的是vue-awsome-swiper)回调中禁止下拉。该下拉组件在IOS端因为-webkit-overflow-scrolling: touch;存在冲突造成无法下拉。fastclick问题的回答,发现在QQ内置打开网页还是存在问题。
image

@victorylin
Copy link

@uncleLian 方法2:如果同时有上下左右的滑动,建议在源码增加一个属性,用于左右滑动(我左右滑动用的是vue-awsome-swiper)回调中禁止下拉。针对方法2,有代码可以参考一下么,谢谢了。

@bigy6241
Copy link

@uncleLian 你好可是我完成了修改但是没有生效,,请问这是为什么!

@uncleLian
Copy link

@bigy6241 @victorylin 基于Loadmore组件的一些问题,我花了点时间,写了篇博文集中总结一下,可以看看。如还有其他问题,请详细列出,可以帮忙看看。http://liansixin.win/2017/08/01/mint-ui/

@bigy6241
Copy link

bigy6241 commented Aug 4, 2017

我遇到了一个悲伤 的问题,就是修改源码不生效,npm 5.0 后来我就吧mint-ui从node_modules中考到本地修改common.js . 然后咋修改的时候e.preventDefault 和 e.stopPropagation()添加在touchend事件的判断中

var distance = (this.currentY - this.startY) / this.distanceIndex;
      var distanceX = (this.currentX - this.startX) / this.distanceIndex;
      if (this.direction === 'down' && this.getScrollTop(this.scrollEventTarget) === 0 && this.translate > 0) {
        e.preventDefault();
        e.stopPropagation(); 
        this.topDropped = true;
        if (Math.abs(distanceX) < 100 && Math.abs(distance) > 5 &&this.topStatus === 'drop') {
          this.translate = '0';
          this.topStatus = 'loading';
          this.topMethod();
        } else {
          this.translate = '0';
          this.topStatus = 'pull';
        }
      }
      if (this.direction === 'up' && this.bottomReached && this.translate < 0) {
        e.preventDefault();
        e.stopPropagation(); 
        this.bottomDropped = true;
        this.bottomReached = false;
        if (Math.abs(distanceX) < 100 && Math.abs(distance) > 5 &&this.bottomStatus === 'drop') {
          this.translate = '0';
          this.bottomStatus = 'loading';
          this.bottomMethod();
        } else {
          this.translate = '0';
          this.bottomStatus = 'pull';
        }
      }

因为我这里在测试的时候直接放在touchend中的时候会直接吧fastclick的所有事件都阻止掉

@baskinwind
Copy link

我也碰到这个坑了,但是也有不用改源码的方式。

因为滚动触发了 touch 事件,而 fastclick 会将 touch 事件转换为 click ,所以出现了滚动时触发了元素的 touch 事件,转而触发了 click ,而想要触发一个元素的正真 click 事件,给元素加上class="needsclick" 就可以了,所以有下面的解决思路:
在会触发点击的元素内盖上一层元素,点击事件在这个盖的元素上处理,然后给这个元素加上 class="needsclick" (只要元素加上这个 class 这个元素上的点击事件就是正常的 click 也就不会因为 touch 事件而触发 click 处理函数了)

dom 结构大概是这样

div.box1
    div.needsclick @click=‘handleClick’
    div.content

box1 为最外层元素 position: relative;
needsclick 为覆盖元素 position: absolute; 大小与 box1 一致完全的覆盖在 content 元素上
content 为内容

写在最后:在 box1 上加 needsclick 是不起作用的,因为当滑动的时候我们不是在 box1 上触发了
touch 而是它的子元素,所以在 box1 上监听 click 其实处理的它子元素冒泡上来的 touch 事件(而 touch 事件已经被处理成了 click ),即使 box1 上触发的是真正的 click 事件,所以才有了覆盖的那一层,当然我们可以给每个 box1 下的内容都加上 class="needsclick" 但这个体验感觉不是很好,应该也是行的通的,但一想到 box1 下面的元素之多(而且基本上仅仅是为了显示),我想想还是算了。

所以才有了这个方案:所有的点击都触发在覆盖元素的那一层,而 content 元素永远都点击不到,因为覆盖元素的点击事件是真正的 cilck 所以也就不存在了因为 touch 事件而触发的 click 了,问题算是半完美解决,因为这会导致 content 中的内容不能点,这算是一个小 bug ,但完美的方法也说了就是给每个 box1 中的元素都加上 class="needsclick" 根据需求加吧。

@lyh2668
Copy link

lyh2668 commented Nov 2, 2017

@acccco 你的思路可以结合derectives解决

@Ninnka
Copy link

Ninnka commented May 15, 2018

@uncleLian 其实通过加大distance的临界值来判断是不太合适的,我认为应该判断滑动的角度来判断是应该垂直滑动还是水平滑动。我修改代码的步骤是这样的:
1.在handleTouchStart方法中,加入

this.startX = event.touches[0].clientX;

2.在handleTouchMove方法中,修改为

this.currentY = event.touches[0].clientY;
this.currentX = event.touches[0].clientX;
const diffX = this.currentX - this.startX;
const diffY = this.currentY - this.startY;
if (Math.abs(diffX) / Math.abs(diffY) > Math.tan(30 * Math.PI/180)) {
  return;
}

此外,我是修改lib/loadmore/index.js文件后才生效的

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants