Javascript - 移动H5页面禁用客户端自带的下拉刷新同时实现页面滚动

3 篇文章 0 订阅
1 篇文章 0 订阅

关键字:移动端,无下拉,可滚动页面

在做移动端的H5页面时,由于手机自有的特性,整个页面具有下拉刷新功能。但如果我们仅仅是做展示页面,不希望下拉刷新,但同时也想保留整个页面的正常上下滚动,该如何做呢?


实现要点 

  1. 禁用body上的touchmove事件
  2. 设置恰当的元素布局
  3. 使用matrix实现页面正常上下滚动
  4. 给body元素设置高度

禁用body上的touchmove事件

document.body.addEventListener('touchmove', (e) => {
  e.preventDefault();
}, { passive: false });

设置恰当的元素布局

html

<header>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
    <meta name="format-detection" content="telephone=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
</header>
<body>
  <div id="container">
    <div id="content">
    </div>
  </div>
</body>

css

#container {
    height: 100%; // 在移动端,高度需要从当前环境中获取,100%无效
    overflow: hidden;
    position: absolute;
    touch-action: none;    
}

#content {
    position: absolute;
}

使用matrix实现页面正常上下滚动

    let contentTop = 0; // 记录要滚动元素的top值,默认情况为0,因为默认显示时,内容的头部时紧挨着容器的
    const getTouchObj = (event) => ((touches) => ('0' in touches ? touches[0] : null))(event.targetTouches || event.originalEvent.targetTouches);
    const windowHeight = getWindowHeight() * 0.8 * 0.786; // 滚动元素的可显示部分的高度,这个值通常都比滚动部分的高度小,不然就不需要滚动显示了。
    const getPos = (touchObj) => ({ x: touchObj.pageX, y: touchObj.pageY, time: new Date() });
    const getOffsetY = (start, endPos) => endPos.y - start;

    const getScrollEl = () => $('#content'); // 滚动元素

    const getContentHeight = () => getScrollEl().height(); // 滚动元素的高度

    const getRealOffset = (offset, top) => {
      if (offset > 0) { // 处理下滑
        if (offset + top <= 0) return offset; // 下滑的距离没有超出顶部
        return -top; // 下滑的距离超出了顶部
      }
      if (offset < 0) { // 处理上滑
        if (Math.abs(offset) + Math.abs(top) + windowHeight <= getContentHeight()) return offset; // 上滑的距离没有超出底部
        return -(getContentHeight() - Math.abs(top) - windowHeight); // 上滑的距离超出了底部
      }
      return 0;
    };
    let startY = 0;

    getScrollEl().on('touchstart', (e) => { // 监听记录滑动的开始Y坐标
      startY = getPos(getTouchObj(e)).y;
    });

    getScrollEl().on('touchmove', (e1) => {
      ((offsetY) => {
        const offset = getRealOffset(offsetY, contentTop); 
        //        this.setState({ offset });
        if (Math.abs(offset) > 1) {
          contentTop += offset;
          getScrollEl().css('transform', `matrix(1, 0, 0, 1, 0, ${contentTop})`);
          //          console.log('real offset', offset, 'new top', contentTop);
        }
      })(getOffsetY(startY, getPos(getTouchObj(e1))));
      startY = getPos(getTouchObj(e1)).y; // 更新当前的滑动Y坐标
    });

结尾

总算可以说些废话了,赶时间的飘过。

禁止body上使用touchmove事件的参考忘记是从哪里copy过来的了,但真的很管用,一放到代码中,整个页面就不能动了。但是我的页面高度超出了屏幕,因此,我还得继续想办法。

最后,我找到了matrix,然后知道了国内有个大牛叫张鑫旭。其实matrix用来实现页面的滚动有点屈才了。

对于项目实施来说,能用就行。上面的代码我是用起来了,但我知道这不是最好的方案。

编程也可以是一门艺术,希望各位大侠多多指教。先谢谢各位的建议。

参考:

 张鑫旭-理解CSS3 transform中的Matrix(矩阵)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明天好,会的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值