IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> React中实现图片预加载、延迟加载、上拉加载、下拉更新 -> 正文阅读

[JavaScript知识库]React中实现图片预加载、延迟加载、上拉加载、下拉更新

1.jsx代码

import { Component } from "react";
import '../component/list.less'
import { searchCar } from '../api/index'
import love from '../assets/爱心.gif';
import load from '../assets/images(1)/loading.gif'
import arrow from '../assets/search/左箭头.gif'
import magnifier from '../assets/search/小放大镜.gif'
import sort from '../assets/search/排序箭头.gif'
import brand from '../assets/search/黑色下箭头.gif'
import funnel from '../assets/search/漏斗.gif'
import right from '../assets/search/右箭头.jpg'

class List extends Component {
    constructor(...args) {
        super(...args)
        this.state = {
            list: [],
            load: 'block',
            Loading: false,
            flag: true
        }
        this.CarArray = []
        this.page = 1;
        this.ImgList = []
        this.CarCount = 0;
        this.ImageCount = 0; //计次(统计图片数量)
        this.count = 1;
    }
    // 接口方法
    async searchCar() {
        return await searchCar({
            page: this.page,
            mod: ''
        })
    }
    FnDate() {
        this.CarArray = []
        this.page = 1;
        this.ImgList = []
        this.CarCount = 0;
        this.ImageCount = 0; //计次(统计图片数量)
        this.count = 1;
    }
    // 钩子函数
    async componentDidMount() {
        await this.FnInit()
        // 监听个页面的滚动
        document.onscroll = this.FnDelayMore.bind(this);

    }
    // 图片预加载
    imgState(item) {
        if (item.imgState) {
            return `http://www.ibugthree.com/${item.img_src}`;
        } else {
            return `http://www.ibugthree.com/default.gif`;
        }
    }
    //设置高度
    // whether 0不需要 1需要 (设置图片)
    FnSetHeight(whether) {
        for (let i = 0; i < this.CarArray.length; i++) {
            let json = this.CarArray[i]; //每一条数据
            this.CarCount = this.EveryHeight * i; //每一条数据的高度
            json.height = this.CarCount; //每一条数据的高度添加到json中
            //  求出每个数据的高度
            if (this.CarCount > this.viewHeight) {
                //不需要加载的
                json.imgState = 0;
            } else {
                // 需要加载出来的
                json.imgState = 1;

                if (whether) {
                    //是否需要添加图片
                    let URL = `http://www.ibugthree.com/${json.img_src}`;
                    this.ImgList.push(URL);
                }
            }
        }
    }
    // 上拉加载更多
    async FnDelayMore() {
        this.CarArray = this.state.list
        // 延迟加载
        //可视区的高度
        this.viewHeight = document.documentElement.clientHeight;
        // 滚动高度
        this.roll = document.documentElement.scrollTop || document.body.scrollTop;
        // 滚动高度+可视区的高度 = 大于页面的高度
        this.ScrollHeight = this.roll + this.viewHeight;

        for (var i = 0; i < this.CarArray.length; i++) {
            let Car = this.CarArray[i];
            if (this.roll + this.viewHeight > Car.height) {
                Car.imgState = 1;
                this.setState({
                    list: this.CarArray
                })
            }
        }

        // 加载更多
        if (
            this.ScrollHeight >= (this.refs.loadMore.scrollHeight - 1) && this.state.flag
        ) {
            this.setState({
                flag: false
            })
            this.count = 1;
            for (let i = 0; i < this.CarArray.length; i++) {
                var Img = new Image();
                let URL = `http://www.ibugthree.com/${this.CarArray[i].img_src}`; //图片地址
                Img.src = URL;
                Img.onload = async () => {
                    this.count++;
                    if (this.count >= this.CarArray.length) {
                        this.setState({
                            Loading: true,
                            flag: true
                        })
                        this.page++
                        let CarData = await this.searchCar();
                        this.CarArray = this.CarArray.concat(CarData);
                        // 所有的数据设置高度
                        this.FnSetHeight();

                        this.setState({
                            list: this.CarArray,
                            Loading: false
                        });
                    }
                }
            }

        }
    }


    // 预加载初始化
    async FnInit() {
        //重新加载接口
        this.CarArray = await this.searchCar();
        this.setState({
            list: this.CarArray
        });
        // 可视区的高度
        this.viewHeight = document.documentElement.clientHeight;
        // 滚动高度
        this.roll = document.documentElement.scrollTop || document.body.scrollTop;
        // 整体的高度
        this.EveryHeight = this.refs.loadMore.offsetHeight / this.CarArray.length;
        this.FnSetHeight(1); //设置高度
        // 图片预加载
        this.ImgList.push("http://www.ibugthree.com/default.gif");
        for (let i = 0; i < this.ImgList.length; i++) {
            let oImage = new Image();
            let URL = this.ImgList[i]; //图片地址
            oImage.src = URL;
            oImage.onload = () => {
                this.ImageCount++;
                if (this.ImageCount >= this.ImgList.length) {
                    // 数据加载完成后改为false
                    this.setState({
                        list: this.CarArray,
                        load: 'none'
                    });

                }
            }
        }
    }

    //下拉刷新
    FnStart(ev) {
        this.refs.loadMore.classList.remove("active");
        this.startY = ev.changedTouches[0].pageY; //拖动的高度(鼠标距离顶部的距离)
        this.PageY = this.startY - this.refs.loadMore.getBoundingClientRect().top; //获取鼠标距离loadmore顶部的距离

        this.refs.loadMore.ontouchmove = this.FnMove.bind(this)
        this.refs.loadMore.ontouchend = this.FnEnd.bind(this)
    }
    FnMove(ev) {
        this.moveY = ev.changedTouches[0].pageY;
        // eslint-disable-next-line
        if (this.moveY > this.startY && this.roll == 0) {
            this.Y = this.moveY - this.PageY - 110; //向下移动的值
            this.scale = 1 - this.Y / 736;
            if (this.scale <= 0.54) {
                this.scale = 0.54;
            }
            this.refs.loadMore.style.transform = `translate(0,${this.Y * this.scale
                }px)`;
            ev.preventDefault && ev.preventDefault();
        }


    }
    async FnEnd(ev) {
        this.UpY = ev.changedTouches[0].pageY;
        this.refs.loadMore.classList.add("active");
        this.refs.loadMore.style.transform = `translate(0,0)`;
        this.CarArray = this.state.list
        ev.preventDefault && ev.preventDefault();

        // eslint-disable-next-line
        if (this.UpY > this.startY && this.roll == 0) {
            //所有数据恢复初始状态
            this.FnDate();
            this.setState({
                list: this.CarArray
            });
            this.state.list = await this.searchCar();
            //图片预加载 设置高度
            await this.FnInit();
            this.setState({
                load: 'none'
            })
        }
    }


    render() {
        return (
            <div>
                <div class="carhome">
                    <div class="header">
                        <div class="header-top">
                            <div class="home-page">
                                <img src={arrow} alt="" class="left-arrow" />
                                <div class="page">首页</div>
                            </div>
                            <div class="search">
                                <img src={magnifier} alt="" class="magnifier" />
                                <input
                                    type="text"
                                    placeholder="品牌车系/车身类型/其他关键字"
                                    class="search-bar"
                                />
                            </div>
                        </div>
                        <div class="header-bottom">
                            <div class="tab">
                                <div class="sort">
                                    <div class="sort-text">排序</div>
                                    <img src={sort} alt="" class="sort-arrow" />
                                </div>
                                <div class="brand">
                                    <div class="brand-text">品牌</div>
                                    <img src={brand} alt="" class="brand-arrow" />
                                </div>
                                <div class="price">
                                    <div class="price-text">价格</div>
                                    <img src={brand} alt="" class="price-arrow" />
                                </div>
                                <div class="mileage">
                                    <div class="mileage-text">车龄/里程</div>
                                    <img src={brand} alt="" class="mileage-arrow" />
                                </div>
                                <div class="color">
                                    <div class="color-text">车龄/里程</div>
                                    <img src={funnel} alt="" class="color-funnel" />
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="main">
                        <div
                            class="main-content"
                            ref='loadMore' onTouchStart={this.FnStart.bind(this)}
                        >
                            <div class="car-box">
                                <div class="car-series">
                                    <div class="content-top">
                                        <div class="car-title">选择车系</div>
                                        <img src={right} alt="" class="right-arrow" />
                                    </div>
                                    <div class="content-bottom">
                                        <div class="content">
                                            为你找到
                                            <div class="num1">3524</div>
                                            辆车 可归为
                                            <div class="num2">379</div>
                                            个车系
                                        </div>
                                    </div>
                                </div>
                            </div>
                            {/* <列表 */}
                            <div className="list">
                                <div className="list-ul" >
                                    {this.state.list.map((item) => <div className="list-li" key={item.ID}>
                                        <img src={love} alt="" className="love" />
                                        {/* eslint-disable-next-line */}
                                        <img src={this.imgState(item)} className="car" />
                                        <div className="list-content">
                                            <div className="list-title">
                                                {item.tit_con}
                                            </div>
                                            <div className="car-year">
                                                <div className="year">{item.buy_time}|</div>

                                                <div className="kilometre">{item.kilometre}万公里</div>
                                            </div>
                                            <div className="car-price">
                                                <div className="present-price">{item.nal_price}万</div>
                                                <div className="down-payments">首付{item.down_payments}万</div>
                                            </div>

                                            <div className="label">
                                                <div className="self-support">优惠自营</div>
                                                <div className="no-reason">七天无理由退车</div>
                                                <div className="new">95成新</div>
                                            </div>
                                        </div>
                                    </div>)}
                                    <div className="loading" style={{ display: this.state.Loading }}>Loading...</div>
                                    {/* 加载 */}
                                    <div className='load' style={{ display: this.state.load }}>
                                        <img src={load} alt="" />
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                   
                </div>
            </div>
        )
    }
}
export default List

2.css样式

// css初始化
body {
    margin: 0;
}

/* 去掉a的下划线 */
a {
    text-decoration: none;
}

/* 搜索框去除边框 */
input {
    border: 0;
    /* 设置背景颜色为透明 */
    background-color: transparent;
    /* 去掉外轮廓 */
    outline: none;
}

/* 图片的空白间隙 */
img {
    vertical-align: middle;
}

// css初始化结束

.carhome {

    //头部
    .header {
        width: 750px;
        height: 151px;
        position: fixed;
        z-index: 20;
        background: #fff;

        // header top盒子
        .header-top {
            width: 750px;
            height: 102px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            box-sizing: border-box;
            padding: 0 30px;

            // 首页(左边布局)
            .home-page {
                width: 103px;
                height: 102px;
                display: flex;
                align-items: center;
                justify-content: center;

                .left-arrow {
                    width: 17px;
                    height: 33px;
                    background: #060606;
                    margin-right: 11px;
                }

                .page {
                    font-size: 24px;
                    color: #050505;
                }
            }

            // 搜素(右侧布局)
            .search {
                margin-left: 24px;
                width: 592px;
                height: 54px;
                border: 1px solid #f4f4f4;
                background: rgba(255, 255, 255, 0.6);
                border-radius: 25px;
                display: flex;
                flex: 1;
                align-items: center;
                justify-content: center;

                // 放大镜
                .magnifier {
                    width: 25px;
                    height: 28px;
                    margin-right: 8px;
                }

                .search-bar {
                    width: 330px;
                    height: 54px;

                    &::placeholder {
                        font-size: 20px;
                        color: #c4c4c4;
                    }
                }
            }
        }

        // header bottom盒子
        .header-bottom {
            width: 750px;
            height: 49px;

            // 选项卡
            .tab {
                height: 49px;
                display: flex;
                align-items: center;
                justify-content: space-between;
                box-sizing: border-box;
                padding: 0 33px;

                // 排序
                .sort {
                    display: flex;
                    align-items: center;
                    justify-content: center;

                    .sort-text {
                        font-size: 22px;
                        color: #f93300;
                        margin-right: 9px;
                    }

                    .sort-arrow {
                        width: 13px;
                        height: 8px;
                    }
                }

                // 品牌
                .brand {
                    display: flex;
                    align-items: center;
                    justify-content: center;

                    .brand-text {
                        font-size: 20px;
                        color: #000000;
                        margin-right: 9px;
                    }

                    .brand-arrow {
                        width: 13px;
                        height: 8px;
                    }
                }

                // 价格
                .price {
                    display: flex;
                    align-items: center;
                    justify-content: center;

                    .price-text {
                        font-size: 20px;
                        color: #000000;
                        margin-right: 9px;
                    }

                    .price-arrow {
                        width: 13px;
                        height: 8px;
                    }
                }

                // 里程
                .mileage {
                    display: flex;
                    align-items: center;
                    justify-content: center;

                    .mileage-text {
                        font-size: 20px;
                        color: #000000;
                        margin-right: 9px;
                    }

                    .mileage-arrow {
                        width: 13px;
                        height: 8px;
                    }
                }

                // 颜色
                .color {
                    display: flex;
                    align-items: center;
                    justify-content: center;

                    .color-text {
                        font-size: 20px;
                        color: #000000;
                        margin-right: 9px;
                    }

                    .color-funnel {
                        width: 17px;
                        height: 17px;
                    }
                }
            }
        }
    }

    // 中间main
    .main {
        height: 100%;
        padding-top: 151px;

        //过渡动画
        .active {
            transition: 0.15s ease-in all;
        }

        .load-on {
            position: absolute;
            width: 100px;
            height: 100px;
            background: url(../assets/refreshIng.gif);
            background-size: cover;
            left: 0;
            right: 0;
            margin: auto;
        }

        .main-content {
            position: relative;
            z-index: 15;
            background: #fff;

            .car-box {
                width: 750px;
                height: 175px;
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                // margin-top: 18px;
                padding: 0 25px;
                box-sizing: border-box;

                // 选择车系
                .car-series {
                    width: 705px;
                    height: 115px;
                    box-shadow: 0px 0px 10px 0px #ccc;
                    background: #ffffff;

                    // 上边内容
                    .content-top {
                        width: 705px;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        margin-top: 10px;

                        .car-title {
                            font-size: 27px;
                            color: #424242;
                        }

                        .right-arrow {
                            width: 31px;
                            height: 31px;
                        }
                    }

                    // 下边内容
                    .content-bottom {
                        width: 705px;
                        margin-top: 18px;
                        text-align: center;

                        .content {
                            font-size: 20px;
                            color: #909090;

                            .num1 {
                                display: inline;
                                color: #bd9a8b;
                            }

                            .num2 {
                                display: inline;
                                color: #bd9a8b;
                            }
                        }
                    }
                }
            }

            // 列表
            .list {
                position: relative;
                z-index: 5;
                width: 750px;

                .list-ul {
                    width: 750px;

                    .loading {
                        width: 750px;
                        height: 40px;
                        line-height: 40px;
                        text-align: center;
                        font-size: 30px;
                        background: #fff;
                        color: #ccc;
                    }

                    .list-li {
                        position: relative;
                        width: 750px;
                        height: 258px;
                        border-bottom: 1px solid #e8e8e8;
                        display: flex;
                        align-items: center;
                        justify-content: space-around;
                        box-sizing: border-box;

                        .love {
                            position: absolute;
                            width: 30px;
                            height: 26px;
                            top: 97px;
                            right: 26px;
                        }

                        // 图片
                        .car {
                            width: 248px;
                            height: 187px;
                            line-height: 187px;
                            border-radius: 10px;
                            padding-left: 15px;
                            margin-right: 19px;
                        }

                        // 内容
                        .list-content {
                            display: flex;
                            flex-direction: column;
                            height: 180px;
                            width: 430px;
                            box-sizing: border-box;
                            margin-top: -20px;

                            // 标题
                            .list-title {
                                font-size: 26px;
                                height: 60px;
                                line-height: 40px;
                                color: #272727;
                                font-weight: 700;
                                box-sizing: border-box;
                            }

                            // 公里数
                            .car-year {
                                padding-top: 21px;
                                width: 100%;

                                .year {
                                    display: inline;
                                    font-size: 19px;
                                    color: #989898;
                                }

                                .kilometre {
                                    display: inline;
                                    font-size: 14px;
                                    color: #9c9c9c;
                                    padding-left: 5px;
                                }
                            }

                            // 价格
                            .car-price {
                                width: 100%;
                                margin-top: 10px;

                                .present-price {
                                    display: inline;
                                    font-size: 25px;
                                    color: #d96736;
                                }

                                .down-payments {
                                    display: inline;
                                    font-size: 21px;
                                    color: #b3b3b3;
                                    margin-left: 7px;
                                }
                            }

                            // 标签
                            .label {
                                width: 100%;
                                height: 24px;
                                margin-top: 10px;
                                display: flex;
                                align-items: center;

                                .self-support {
                                    display: inline;
                                    height: 24px;
                                    line-height: 24px;
                                    background-image: linear-gradient(to right, #f0e6b1, #edb573);
                                    border-radius: 3px;
                                    font-size: 14px;
                                    color: #774e04;
                                    text-align: center;
                                    margin-right: 6px;
                                    padding: 2px 4px;
                                }

                                .no-reason {
                                    display: inline;
                                    height: 20px;
                                    line-height: 23px;
                                    text-align: center;
                                    border: 1px solid #f93300;
                                    font-size: 15px;
                                    color: #f93300;
                                    border-radius: 3px;
                                    margin-right: 5px;
                                    padding: 2px 4px;
                                }

                                .new {
                                    display: inline;
                                    height: 20px;
                                    line-height: 23px;
                                    text-align: center;
                                    border: 1px solid #f93300;
                                    font-size: 15px;
                                    color: #f93300;
                                    border-radius: 3px;
                                    padding: 2px 4px;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    // loading加载页
    .LoadHide {
        width: 100vw;
        height: 100vh;
        background: #fff;
        position: fixed;
        top: 0;
        left: 0;
        z-index: 999;

        img {
            position: absolute;
            width: 200px;
            height: 200px;
            top: 50%;
            left: 50%;
            margin-top: -100px;
            margin-left: -100px;
        }
    }
}
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-07 10:43:35  更:2021-09-07 10:45:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 17:12:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码