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;
}
}
}
|