zoukankan      html  css  js  c++  java
  • 在React中引入IScroll插件做滚动

    最近做一个H5项目,数据交互量比较大,很多页面都是从后台拿过来数据做一个列表显示,这自然就遇到了滚动。

    刚开始我直接使用css做法,直接添加overflow: scroll;但在微信端用户滑动会直接将整个页面拖动,露出顶部的域名和底部的黑色背景。用户反映体验不好,要改……好吧,自己动手。但这并不是好改的,因为在React中都是构建的是虚拟DOM,直接操作DOM也会对性能有一定影响。这时候网上搜了一下,拿出一个解决方案,献出部分代码:

      

    import React from 'react';
    import { render } from 'react-dom';
    import Router from './app/router';
    import '../common/css/base.styl';
    import '../common/css/waaStyle.styl';
    import '../common/css/page.styl';
    var divDom = document.createElement('div');
    divDom.setAttribute('id', 'wrap');
    
    document.body.appendChild(divDom);
    document.body.addEventListener("touchmove",function (e) {
        e.preventDefault();
    },false);
    render(<Router />, divDom);

    这是在React的根页面下直接禁用touchmove事件,禁止用户touchmove,可以达到不出现域名和黑色边框的效果。

    由于禁止touchmove事件,在需要列表滚动的地方,overflow:scroll;监听不到touchmove了,滑动变得无效,怎么解决呢?我们可以在需要滚动的地方禁止冒泡事件:

    //首先要获取需要禁止冒泡事件的dom,由于React是构建虚拟的dom,可以这样拿到dom:ref= {(ref) => {this.dom = ref}};
    
    componentDidMount () {
          this.dom.addEventListener("touchmove",function (e) {
            e.stopPropagation();
          },false);  
    } 
    
    //dom在页面挂载完成后,禁止冒泡事件。   

      加上这样的代码后,就会发现,整个页面仍然是禁止滑动,列表页可以正常滚动,但是,当列表滚动到底的时候,用户继续滑动,整个页面仍然会跟着滑动,又露出我们不想看到的部分,感觉好气呀……

    冷静分析一下,这条路是走不通的,由于列表区域禁止了冒泡事件,那么用户只要在列表区域滑动,那么你在body上做的禁止滑动就是没有效果的!

      万般无奈下,我有搬来了我的老伙计:IScroll.js。之所以选他,因为他有一个非常有用的方法:refresh();我只要在componentDidMount中实例化Iscroll,并且在React数据更新后再次refresh就可以了。那么开始做了。

    React框架中引入我们想要的插件,只要这样做就行:

    import Iscroll from "moudle/iscroll/Iscroll";

    然后页面挂载完成后我们进行实例化

    componentDidMount() {
      setTimout(function () {//由于手机性能的原因,我们在定时器里面进行实例化
        this.myIScroll = new IScroll("#dom",{
        mouseWheel: true,
        bounce: true,
        scrollbars: false,
    });  
      },10);
    }

    一但React检测到数据有更新,他就会自动刷新页面,那么我们这个时候需要重新刷新IScroll:

    componentDidUpdate() {
      this.myIScroll.refresh();  
    }

    代码做到这里,我们就会发现,即使禁止touchmove事件,我们依然可以使用滚动列表,问题完美解决!不过,此时客户大手一挥,指着我们的滚动条,这个滚动条有点丑呀,能不能把它做得科技感一些……哎,数不清的星星,改不完的需求啊,不过,这个对于我们无(xia)所(chui)不(niu)能(bi)的程序猿也是可以做得。在IScroll中,它的滚动条是由两个做了定位的div构成的,那么

    我们在实例化IScroll的时候参数中设置:

    this.myIScroll = new IScroll("#dom",{
    scrollbars: 'custom',//即scrollbars的值设置成字符串:“custom”即可
    });

    然后我们在样式表中使用两个类名:

    .iScrollIndicator和.iScrollVerticalScrollbar.iScrollLoneScrollbar写入样式,这样组成滚动条的两个div就可以长成我们希望的样子啦!
    但是根据需求,有的列表很长,需要分页加载,那么就需要判断用户拖动后是否需要加载下一页的数据了。
    基本的思路是,利用this.y得到向上移动的距离,用里面框的高度减去移动的距离,再减去外面框的高度,如果小于某一个高度,我们去请求数据,之后重新渲染就行了。但是,我查阅了IScroll的相关代码,文档上并没有写出内外两个框高度的接口,也曾经试着自己在源码里添加获得框高度的方法,但是在实例化后获取这个值总会有各种各样的问题。最后经过仔细研究IScroll源码,发现外面框的高度就是实例化后的:this.wrapperHeight,而里面框的高度就是:this.scrollerHeight,这样我们减去this.y的绝对值后,就可以判断出是否需要加载新的数据了。给大爷们线上代码:
    componentDidMount () {
            var self = this;
            const options = {
                preventDefault: false,
                zoom: false,
                mouseWheel: true,
                probeType: 3,
                bounce: true,
                scrollbars: true,
            };
            this.iScrollInstance = new IScroll(this.scrollContent,options);
            this.iScrollInstance.on('scrollEnd', function() {
    
                var shouldGet = this.scrollerHeight + this.y - this.wrapperHeight;//注意this.y一定是非正数,所以这里是加啦!
    
                if (shouldGet < 200 && this.directionY === 1 && !self.state.loading) { //我这里设置的临界值是200,即列表滚动结束后,如果里框的高度还有小于200px的内容没有显示过就会去加载新的数据。
                    if(self.state.pageNo >= self.state.totalPage) {
                        Action.update({noMore: true});
    
                    } else {
                        self.state.pageNo ++;
                        Action.getList({pageNo: self.state.pageNo});
                    }
                }
            });
        }

    做到这里,我们利用IScroll想解决的需求都可以满足了……






  • 相关阅读:
    LALR(1)语法分析生成器--xbytes
    <<摩托车修理技术与禅>>读书笔记
    xscript脚本
    CentOS安装Erlang
    TCP中close和shutdown之间的区别
    Erlang高阶函数
    深度学习小记
    mac平台打造犀利的Android Studio开发环境
    MAC中如何配置两套android-sdk环境
    Ubuntu虚拟机编译Android6.0总结
  • 原文地址:https://www.cnblogs.com/zhangbob/p/7991929.html
Copyright © 2011-2022 走看看