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

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

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


实现要点 

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

禁用body上的touchmove事件

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

设置恰当的元素布局

html

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(矩阵)

你可能感兴趣的:(代码,H5,Javascript)