图片懒加载

181 阅读3分钟

效果:




原理:

1.设置img的初始src为不请求的空白路径
2.将资源路径赋值到img标签的data-xx属性中,而不是src属性
3.获取img节点距离浏览器顶部的距离,如果小于或等于浏览器窗口的可视高度,那么就将data-xx的值赋值到src里去

要点:

  • 获取某个容器下的img:
let img_div = document.getElementsByClassName('img_cantent')[0].getElementsByTagName('img')
  • 属性赋值:
img_div[i].src = img_div[i].getAttribute('data-src')
  • 容器滚动事件
<div onScroll={this.scroll.bind(this)}></div>
  • 在每个img标签外层加一个固定高度的div容器,否则初始时找不到有效img高度,导致所有的img请求都发送

示例:

img.js:

import React, { Component } from 'react'
import './img.less'

/* 原理:
将资源路径赋值到img标签的data-xx属性中,而不是src属性
获取img节点距离浏览器顶部的距离,如果小于或等于浏览器窗口的可视高度,那么就将data-xx的值赋值到src里去 */

export default class img extends Component {
    constructor(props) {
        super(props)
        this.state = {
            img_src: [
                //图片路径不能相同,如果图片路径都相同,看不出懒加载的请求效果
                { src: 'http://img3.imgtn.bdimg.com/it/u=309842420,1506146809&fm=26&gp=0.jpg', id: 0 },
                { src: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574244772&di=1f275f4de0a8fcd30159ef65f9bae04f&imgtype=jpg&er=1&src=http%3A%2F%2Fnews.mydrivers.com%2Fimg%2F20120310%2F2012031010521034.jpg', id: 1 },
                { src: 'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2307547838,688347192&fm=26&gp=0.jpg', id: 2 },
                { src: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574244799&di=6ec0c47289c41b16a43aa8ee82f5b8c9&imgtype=jpg&er=1&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2Fc%2F55481ddb63abd.jpg', id: 3 },
                { src: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574244814&di=8b9527e2ef6173354328c860b65d3b41&imgtype=jpg&er=1&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201209%2F07%2F20120907181858_dYBtS.jpeg', id: 4 },
                { src: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574244833&di=972927f0aba4cd1ed88a076a0e5abf45&imgtype=jpg&er=1&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fblog%2F201601%2F13%2F20160113213349_HiTVj.jpeg', id: 5 },
                { src: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574244847&di=34569ecf3ca4e212c8f95d078ef74828&imgtype=jpg&er=1&src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F037d7ec581b0139a84a0e282b8f9462.jpg', id: 6 },
                { src: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574244858&di=0a3b6c6d589ed560ff017797960e601d&imgtype=jpg&er=1&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fblog%2F201512%2F09%2F20151209174557_fZdty.jpeg', id: 7 },
                { src: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574244881&di=1f878cfc16bd94d789d3a3a487ae9f90&imgtype=jpg&er=1&src=http%3A%2F%2Fattach.bbs.miui.com%2Fforum%2F201203%2F11%2F1923091i21c1cg1fux2cnh.jpg', id: 8 },
                { src: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2330041436,3443695532&fm=26&gp=0.jpg', id: 9 },
            ]
        }
    }
    componentDidMount() {
        this.scroll()
        // window.addEventListener('scroll',()=>{//监听整个页面的滚动
        //     this.scroll()
        // })
    }
    // 监听图片容器滚动
    scroll() {
        console.log('scroll')
        let img_div = document.getElementsByClassName('img_cantent')[0].getElementsByTagName('img')

        for (let i = 0; i < img_div.length; i++) {
            let top = img_div[i].getBoundingClientRect().top//图片距离页面顶部距离
            let clientHeight = window.innerHeight//浏览器页面高度

            if (top <= clientHeight - 300) {//图片出现在浏览器页面内时(设置300高度差距为方便看懒加载效果)
                img_div[i].src = img_div[i].getAttribute('data-src')
            }

        }

    }
    render() {
        let { img_src } = this.state
        return (
            <div className='img_cantent' onScroll={this.scroll.bind(this)}>
                {
                    img_src.map((v, i) => {
                        return (
                            <div style={{height:'200px'}} key={v.id}>
                                <img id='img' src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src={v.src} />
                            </div>
                        )
                    })
                }
            </div>
        )
    }
}

img.less:

.img_cantent{
    width: 100%;
    height: 100vh;
    overflow: auto;
    display: flex;
    flex-flow: column;
    align-items: center;
    img{
        width: 300px;
        margin: 10px;
    }
}