1.前言
1.1 懒加载现在基本也是主流的基本功了,用的太多了
1.2 第三方库也非常多,但是我们还需要了解原理滴
1.3 基于上篇文章商城列表
1.4 来一起玩玩吧
2. 效果
3. 分析
- 首先上篇文章是用函数式组件写的,这篇文章需要用到生命周期钩子,所以选用类组件
- 函数式组件和类组件的区别,导致一些写法上的不同 比如传值
- 懒加载代码的书写位置
3.1 懒加载是监听的的图片滚动事件
3.2 所以图片在哪,监听在哪
3.3 图片比较多,所以懒加载直接封装成组件- 一个懒加载组件
LazyImg
只负责图片相关- 一个
Item
组件 就是li
列表具体内容
包含LazyImg
和标题- 一个整合组件
App
就是ul
用来遍历操作 具体的Item
- 具体细节 ,先干起来
分析不动了,就实干
4.懒加载组件 LazyImg
懒加载是单独处理图片的
图片
URL
往下传构造函数和渲染函数都比较简单
麻烦的是钩子 ,懒加载逻辑
4.1 基础结构
这里用了
ref
来获取具体的懒加载标签
class LazyImg extends React.Component { constructor() { super() console.log("懒加载-构造函数") } render() { return ( <img ref="img" alt="" /> ) } componentDidMount() {} }
4.2 具体逻辑
都是在钩子里面写的
- 通过
ref
获取需要拦截的标签- 懒加载嘛,自然需要设置一个等待的loading图片
- 懒加载具体的逻辑封装成一个函数,因为这个懒加载是在监听函数里面执行的,代码太多,维护起来不方便,看着也不够简介
4.3 懒加载核心分析-监听时机-啥时候启动懒加载代码
7.看图分析
- 获取已经滚动的高度,也俗称卷起来的高度
scrollTopHeight
- 窗口的高度
windowHeight
- 图片距离顶部的距离
imgTopHeight
- 图片距离顶部的距离+一个数值 < 滚动高度+窗口的高度
这个数值 自己可以试验,看到多少的时候,进行图片切换不显示懒加载,显示正常的图片,
比方说你想在图片 显示1/3
时,就看见图片,那你的这个数值就写图片的1/3
抱歉 语文学的不好,老师教的好,但是自己表达能力不行
imgTopHeight + 变量< scrollTopHeight + windowHeight)
- 在这个条件成立时切换图片
- 监听函数
5. 懒加载逻辑实现
说了那么多废话,上代码
不过我觉得上面的废话-逻辑梳理比这个代码本身重要的多
componentDidMount() { // console.log(dataList.length); // 设置Loading动画 var img = this.refs.img img.style.background = "url(../img/lazyload.gif) center center no-repeat" var ld = () => { var scrollTopHeight = document.body.scrollTop || document.documentElement.scrollTop var windowHeight = window.innerHeight var imgTopHeight = img.offsetTop; if (imgTopHeight + 150 < scrollTopHeight + windowHeight) { img.src = this.props.src img.onload = () => { img.style.background = "none" } // 取消滚动监听 window.removeEventListener("scroll", ld) } } ld() window.addEventListener("scroll", ld) }
6. Item组件
这个逻辑就简单了 就是传值
不过这个注意和函数式组件的区分 ,写上
this
class Item extends React.Component { constructor() { super(); } //获取属性 添加this render() { return (<li> <LazyImg src={this.props.item.image} /> <h6>{this.props.item.name}</h6> </li> ) } }
7. 整合组件
这里面的数据 也是之前
node
爬虫爬取的,一个js
文件通过
setTimeOut
模拟了一个ajax
请求数据循环的
key
值 不要忘写
class App extends React.Component { constructor() { super(); this.state = { dataList: [] } } render() { return (<ul className="list"> { this.state.dataList.map(item => { return ( <Item item={item} key={item.skuId} /> ) }) } </ul>) } componentWillMount() { // 模拟ajax请求 setTimeout(() => { this.setState({ dataList: dataList }) }, 2000) } }
8. 还是简写说下数据结构
8.1 数据引入
<script src="../js/data.js"></script>
8.2 数据格式
var dataList = [{},{}]
9. 后记?
打完收工,不知道写啥了 吃饭去 哈哈