商城排序
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 乘以-1sortList(this, i);};}
【发上等愿,结中等缘,享下等福,择高处立,寻平处住,向宽处行】
