zoukankan      html  css  js  c++  java
  • react-scrollload

    import React from 'react';
    import { findDOMNode } from 'react-dom';
    import throttle from 'lodash/throttle';
    import { Spin } from '@wind/wind-ui';
    import ReactPlaceHolder from 'react-placeholder';
    /**
     * 需找当前元素最近可滚动的父元素
     * @param {HTMLElement} element 当前元素
     */
    function getScrollParent(element) {
      // const style = (elem, prop) => {
      //   if (getComputedStyle !== undefined) {
      //     return getComputedStyle(elem, null).getPropertyValue(prop);
      //   }
      //   return elem.style[prop];
      // };
      // const overflow = node => style(node, 'overflow') + style(node, 'overflow-x') + style(node, 'overflow-y');
      // 循环判断父节点是否可滚动这里暂不添加,直接去直接父元素
      if (!(element instanceof HTMLElement)) {
        return window;
      }
      let parent = element;
      while (parent) {
        // 当前节点是body或者document
        if (parent === document.body || parent === document.documentElement) {
          break;
        }
        // 当期元素无父节点
        if (!parent.parentNode) {
          break;
        }
        // 判断节点是否含有overflow等属性的值
        if (parent.scrollHeight > parent.clientHeight) {
          return parent;
        }
        // if (/(scroll|auto|inherit)/.test(overflow(parent))) {
        //   return parent;
        // }
        parent = parent.parentNode;
      }
      return window;
    }
    
    let EmptyCompBox = ({ ...props }) => (
      <div {...props}>
        {/* <Spin size="large" className="lazyload-center-spin" /> */}
      </div>
    );
    
    class ScrollLoad extends React.Component {
      state = {
        visible: false,
      };
    
      componentDidMount() {
        let dom = findDOMNode(this); // 取得当前节点
        let parent = getScrollParent(dom);
        // console.log(dom,parent)
    
        this.parent = parent;
        let visible = this.checkVisible(dom, parent); // 初始化检查是否可见
        visible();
        this.scrollHandler = throttle(this.checkVisible(dom, parent), 100);
        parent.addEventListener('scroll', this.scrollHandler, { passive: true });
      }
    
      componentWillUnmount() {
        this.parent.removeEventListener('scroll', this.scrollHandler);
      }
    
      /**
       * 获取当前节点的offsetTop,如果不是直接父节点的话,通过循环获取
       */
      getNodeOffsetTop = (node, parent) => {
        if (!node || !parent) {
          this.setState({ visible: true });
          return 0;
        }
        let current = node;
        let offsetTop = 0;
    
         offsetTop += current.offsetTop
        // ==========ff================
    
        // while (current !== parent && current) {
        //   offsetTop += current.offsetTop;
        //   current = current.parentElement;
        // }
    
        // ==========ff================
        return offsetTop;
      };
    
      /**
       * 检测元素是否可见
       */
      checkVisible = (node, parent) => {
        if (!node || !parent) {
          this.setState({ visible: true });
          return null;
        }
        return () => {
          const { visible } = this.state;
          // 一旦可见下次取消事件监听
          if (visible) {
            this.parent.removeEventListener('scroll', this.scrollHandler);
            return; // 直接返回不执行当次eventListener
          }
          let seenHeight = parent.clientHeight || 0;
          let scrollHeight = parent.scrollTop || 0;
          let currentNode = findDOMNode(this); // 获取最新的dom结构
          let offsetTop = this.getNodeOffsetTop(currentNode, parent);
          // 1. 当偏移高度小于可见高度
          // 2. 初始不可见的时候,当可视高度+滚动高度大于了偏移高度
          // 3. 可以设置preLoad
          // console.log(offsetTop, seenHeight, scrollHeight)
          if (offsetTop <= seenHeight + scrollHeight) { //可视范围内
            this.setState({ visible: true });
          }
        };
      };
    
      render() {
        const { visible } = this.state;
        const { id, className, style } = this.props;
        return (
          <ReactPlaceHolder
            ready={visible}
            customPlaceholder={<EmptyCompBox id={id} className={className} style={style} />}
          >
            {this.props.children}
          </ReactPlaceHolder>
        );
      }
    }
    
    export default ScrollLoad;
    

      

  • 相关阅读:
    在o(N log N)时间内使用恒定的空间复杂度对链表进行排序
    归并排序
    The method of type must override a superclass method解决方式
    android sdk design Iconography
    android sdk design Typography
    android sdk design Metrics and Grids
    android模拟器被点击时总是自动输入C的解决
    “System.Data.Entity.ModelConfiguration.ModelValidationException”类型的未经处理的异常在 EntityFramework.dll 中发生
    js中的this使用
    MVC身份认证 解决办法 测试可行
  • 原文地址:https://www.cnblogs.com/lisiyang/p/13667881.html
Copyright © 2011-2022 走看看