index.tsx
import React, { useEffect, useRef, useState } from 'react'
import "./index.less";
import { getSearchCar } from "./../../api/index";
interface carList {
ID: number;
card_time: string;
tit_con: string;
nal_price: string;
img_src: string;
vehicle_system: string;
mileage: string;
car_price: string
}
export default function YouXin() {
const [title, settit] = useState<carList[]>([]);
let count = 0
let page = 1
const Preload = useRef<HTMLDivElement>(null);
const scrollpage = useRef<HTMLDivElement>(null);
const Loading = useRef<HTMLDivElement>(null);
const getload = () => Preload.current as HTMLDivElement;
const getpage = () => scrollpage.current as HTMLDivElement;
const getding = () => Loading.current as HTMLDivElement;
useEffect(() => {
(async () => {
let carLists: carList[] = await getSearchCar({ page: "1", mod: "大众" });
settit([...carLists]);
for (var i = 0; i < carLists.length; i++) {
let oimage = new Image();
oimage.src = `后端接口地址/${carLists[i].img_src}`;
oimage.onload = () => {
count++;
console.log(count);
if (count === carLists.length) {
getload().style.display = "none";
}
}
}
})();
}, []);
const Fnscroll = async () => {
let scrollTop = getpage().scrollTop;
let viewHeight = getpage().clientHeight;
let scrollHeight = getpage().scrollHeight;
if (Math.trunc(scrollTop + viewHeight) === scrollHeight) {
page++;
let pagelist: carList[] = await getSearchCar({ page: `${page}`, mod: "大众" });
getding().style.display = "block";
setTimeout(() => {
(getding().children[1] as HTMLDivElement).innerText = "加载成功";
setTimeout(() => {
settit([...title, ...pagelist]);
getding().style.display = "none";
(getding().children[1] as HTMLDivElement).innerText = "加载中";
}, 500);
}, 1500);
}
}
return (
<div className="youxin-Body-Box">
<div className="Preload" ref={Preload}>
<img src={require("./../../images/tucheng.png")} alt="" />
</div>
<div className="youxin-BodyBox-header">
<div>
<img src={require("./../../images/youxin-icon_03.jpg")} alt="" />全自营 更放心
</div>
<img src={require("./../../images/youxin-icon_06.jpg")} alt="" />
</div>
<div className="youxin-BodyBox-sort">
<div>综合排序 <img src={require("./../../images/youxin-icon_15.jpg")} alt="" /></div>
<div>品牌 <img src={require("./../../images/youxin-icon_21.jpg")} alt="" /></div>
<div>价格 <img src={require("./../../images/youxin-icon_21.jpg")} alt="" /></div>
<div>筛选 <img src={require("./../../images/youxin-icon_18.jpg")} alt="" /> </div>
</div>
<div className="youxin-BodyBox-content" ref={scrollpage} onScroll={Fnscroll}>
<div className="youxin-BodyBox-List">
{title.map((item, index) => <div className='carList-item' key={item.ID}>
<img src={`http://www.ibugthree.com/${item.img_src}`} alt="" />
<div className=" carList-item-rightBox">
<div className="item-title">
{item.vehicle_system}
</div>
<div className="item-details">
{item.tit_con}
</div>
<div className="item-parameter">
<div>{item.card_time}上牌</div>
<div>{item.mileage}万公里</div>
</div>
<div className="item-Price">
<span>{item.nal_price.substring(0, 2)}</span>{item.nal_price.substring(2, 5)}万 首付
{item.car_price}万
</div>
</div>
</div>)}
<div className="Loading" ref={Loading}>
<img src={require("./../../images/upload.gif")} alt="" /><span>加载中...</span>
</div>
</div>
</div >
</div >
)
}
index.less
.youxin-Body-Box {
width: 100vw;
height: 100vh;
background: #fff;
display: flex;
flex-direction: column;
overflow: hidden;
@keyframes turn {
0% {
-webkit-transform: rotate(0deg);
}
25% {
-webkit-transform: rotate(90deg);
}
50% {
-webkit-transform: rotate(180deg);
}
75% {
-webkit-transform: rotate(270deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
.Preload {
width: 100vw;
height: 100vh;
position: fixed;
left: 0;
top: 0;
background-color: #fff;
>img {
display: block;
width: 60px;
height: 60px;
margin: 370px auto;
animation: turn 1s linear infinite
}
}
.youxin-BodyBox-header {
width: 100vw;
height: 100px;
display: flex;
align-items: center;
justify-content: space-between;
background: #f7f8fa;
>div {
width: 250px;
height: 33px;
font-size: 27px;
margin-left: 27px;
line-height: 33px;
font-weight: 900;
>img {
width: 21px;
height: 33px;
margin-right: 28px;
vertical-align: middle;
}
}
>img {
width: 38px;
height: 30px;
margin-right: 29px;
}
}
.youxin-BodyBox-sort {
width: 100vw;
height: 100px;
display: flex;
justify-content: space-around;
font-size: 23px;
>div {
height: 100px;
line-height: 100px;
>img {
margin-left: 9px;
vertical-align: middle;
}
&:nth-child(1) {
img {
width: 13px;
height: 18px;
}
}
&:nth-child(2),
&:nth-child(3) {
img {
width: 14px;
height: 8px;
}
}
&:nth-child(4) {
img {
width: 15px;
height: 18px;
}
}
}
}
.youxin-BodyBox-content::-webkit-scrollbar {
display: none;
}
.youxin-BodyBox-content {
width: 100vw;
flex: 1;
overflow-y: scroll;
}
.youxin-BodyBox-List {
width: 100vw;
display: block;
.carList-item {
margin: auto;
width: 695px;
height: 187px;
display: flex;
margin-top: 64px;
&:nth-child(1) {
margin-top: 0px;
}
>img {
width: 247px;
height: 187px;
}
.carList-item-rightBox {
width: 422px;
height: 187px;
margin-left: 23px;
.item-details {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;
font-size: 25px;
margin-bottom: 12px;
}
.item-title {
width: 100%;
font-size: 27px;
font-weight: 900;
margin-top: 12px;
}
.item-parameter {
height: 30px;
display: flex;
font-size: 19px;
margin-bottom: 28px;
>div {
padding: 0 15px 0 15px;
background: #f3f3f3;
margin-right: 8px;
}
}
.item-Price {
width: 100%;
font-size: 23px;
color: #ed713c;
>span {
font-size: 29px;
font-weight: 800;
}
}
}
}
.Loading {
width: 100vw;
height: 50px;
display: flex;
text-align: center;
line-height: 50px;
justify-content: center;
align-items: center;
display: none;
font-size: 20px;
>img {
vertical-align: middle;
}
}
}
}
预加载:对求出的数据进行循环,创建 img对象,用onload事件监听,声明一个计数的变量,没加载完成一个img对象,就 ++;然后判断计数的量和请求过来的数据length是否相等,相等就把遮罩层隐藏,
上拉加载: 1.求出滚动元素的scrollTop
2.求出可视区高度
3.求出滚动元素的滚动高度
判断 当 scroll + 可视区高度时 等于 滚动高度时就证明你此时必然触底,此时我们有一个保存页数的变量page ,在我们触底后 page 就+ 1;然后我们求取新一页的数据,然后将上一页和新求取的一页数据合并,达成上拉加载功能,具体一些细节上的问题可以自行更高,仅提供一个构思;
如有高见,可在评论发言