商城排序
HTML 代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>珠峰培训-商品排序</title>
<!--import css-->
<link rel="stylesheet" href="css/reset.min.css"/>
<link rel="stylesheet" href="css/index.css"/>
</head>
<body>
<div class="container">
<!--HEADER-->
<div class="header clear" id="header">
<span>排序:</span>
<a href="javascript:;">上架时间</a>
<a href="javascript:;">价格</a>
<a href="javascript:;">热度</a>
</div>
<!--LIST-->
<ul class="list clear" id="list">
<li><a href="javascript:;">
<img src="img/1.jpg" alt="">
<p>HUAWEI Mate 10 4GB+64GB 全网通版(亮黑色)</p>
<span>¥3899</span>
</a></li>
</ul>
</div>
<!--IMPORT JS-->
<script src="js/index.js"></script>
</body>
</html>
CSS代码
- 不含 reset.css 文件
html, body {
width: 100%;
overflow-x: hidden;
background: #F4F4F4;
font-size: 14px;
color: #555;
}
.container {
margin: 20px auto;
width: 1200px;
overflow: hidden;
}
/*--HEADER--*/
.header {
background: #FFF;
}
.header span {
float: left;
width: 90px;
line-height: 50px;
text-align: center;
}
.header a {
position: relative;
float: left;
padding: 0 15px;
line-height: 50px;
text-align: center;
color: #999;
}
.header a i {
position: absolute;
right: 3px;
top: 50%;
margin-top: -4px;
width: 0;
height: 0;
font-size: 0;
overflow: hidden;
border: 4px solid transparent;
}
.header a i.up {
margin-top: -9px;
border-bottom-color: #999;
}
.header a i.down {
margin-top: 1px;
border-top-color: #999;
}
.header a i.up.bg {
border-bottom-color: #E01D20;
}
.header a i.down.bg {
border-top-color: #E01D20;
}
.header a:hover {
color: #E01D20;
}
/*--LIST--*/
.list {
width: 1205px;
margin-top: 20px;
}
.list li {
margin: 0 10px 10px 0;
float: left;
}
.list li a {
display: block;
padding: 0 16px;
width: 193px;
background: #FFF;
border: 3px solid transparent;
}
.list li a img {
display: block;
width: 100%;
}
.list li a p {
height: 40px;
line-height: 20px;
color: #999;
overflow: hidden;
}
.list li a span {
line-height: 40px;
color: #555;
}
.list li a:hover {
border: 3px solid #E01D20;
}
JS代码
- 获取元素对象:
// 获取元素
let headerBox = document.getElementById('header'),
linkList = headerBox.getElementsByTagName('a'),
listBox = document.getElementById('list'),
productList = listBox.getElementsByTagName('li');
- 基于ajax获取数据
let productData = null;
let xhr = new XMLHttpRequest(); // 创建一个 ajax 实例对象
xhr.open('GET', 'json/product.json', false); // 调用 xhr 的 open 方法
xhr.onreadystatechange = function () {
// 监听 xhr 的 onreadystatechange 事件
if (xhr.readyState === 4 && xhr.status === 200) {
// 如果满足这个条件,就表示当前请求已经顺利完成
productData = xhr.responseText;
}
};
xhr.send(null); // 发送 ajax 请求
- 解析从服务端获取的数据
productData = JSON.parse(productData);
- 数据绑定:基于我们从服务端获取的数据,把页面中需要的数据和 html 结构搞出来,最后把数据和 html 添加到页面中的指定容器中。
let str = ``; // 模板字符串
for (let i = 0; i < productData.length; i++) {
let item = productData[i];
// str 在这里还只是一个字符串,不能通过. 属性名的方式自定义属性
str += `<li data-price="${item.price}"
data-time="${item.time}"
data-hot="${item.hot}">
<a href="javascript:;">
<img src="${item.img}" alt="">
<p>${item.title}</p>
<span>¥${item.price}</span> <br>
<span>上架时间:${item.time}</span> <br>
<span>热度:${item.hot}</span>
</a>
</li>`
}
- 把拼接好的 html 字符串插入到页面的指定容器中(这些拼接好的字符串在没有添加到页面中,再此之前还不是元素)
listBox.innerHTML = str;
- 定义处理排序的方法
let sortList = function (that, index) {
// 用来处理排序逻辑的方法
// 1. 根据 getElementsByTagName 获取的是一个元素集合,而元素集合是一个类数组,如果想调用 sort 进行排序,需要先将类数组转化成数组,数组中 li 并不是克隆出来的,而是原有类数组中元素对象对应的堆内存空间地址。
let productArr = [...productList];
// 2. 基于 sort 按照价格给 li 排序
productArr.sort((a, b) => {
// a 和 b 都是 li 元素对象,所以不能直接相减。
// 我们需要从 li 上面获取到价格
// let innerText = that.innerText;
let aInn, bInn;
let ary = ['data-time', 'data-price', 'data-hot'];
aInn = a.getAttribute(ary[index]);
bInn = b.getAttribute(ary[index]);
let reg = /-/g;
if (index === 0) {
aInn = aInn.replace(reg, '');
bInn = bInn.replace(reg, '')
}
// console.log(aInn, bInn);
return (aInn - bInn) * that.flag; // 排序时使用当前被点击的 a 标签私有的 flag
});
- productArr 排好序后页面中并没有按照价格排列,原因是我们还需要把排好序的 li 依次插入到 ul#list(id 为 list 的 ul)中
for (let i = 0; i < productArr.length; i++) {
listBox.appendChild(productArr[i]);
}
};
7.循环绑定点击事件
for (let i = 0; i < linkList.length; i++) {
linkList[i].flag = -1; // 让每个a标签私有自己的flag,并且在排序时自己管理自己的
linkList[i].onclick = function () {
// 点击价格a标签的时候给li排序
// => 如果你点击某一个a标签的是,想让列表按照当前维度升序排序,就要保证当前a标签的flag是-1;所以我们点击当前a标签的时候,把其他两个a标签的flag重置成-1;
for (let j = 0; j < linkList.length; j++) {
if (linkList[j] !== this) {
// this是当前点击的a标签,!== this就是其他两个
linkList[j].flag = -1; // 重置非当前点击的a标签的flag
}
}
this.flag *= -1; // 给当前点击的a标签上的flag 乘以-1
sortList(this, i);
};
}