商城排序

HTML 代码

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>珠峰培训-商品排序</title>
  6. <!--import css-->
  7. <link rel="stylesheet" href="css/reset.min.css"/>
  8. <link rel="stylesheet" href="css/index.css"/>
  9. </head>
  10. <body>
  11. <div class="container">
  12. <!--HEADER-->
  13. <div class="header clear" id="header">
  14. <span>排序:</span>
  15. <a href="javascript:;">上架时间</a>
  16. <a href="javascript:;">价格</a>
  17. <a href="javascript:;">热度</a>
  18. </div>
  19. <!--LIST-->
  20. <ul class="list clear" id="list">
  21. <li><a href="javascript:;">
  22. <img src="img/1.jpg" alt="">
  23. <p>HUAWEI Mate 10 4GB+64GB 全网通版(亮黑色)</p>
  24. <span>¥3899</span>
  25. </a></li>
  26. </ul>
  27. </div>
  28. <!--IMPORT JS-->
  29. <script src="js/index.js"></script>
  30. </body>
  31. </html>

CSS代码

  • 不含 reset.css 文件
  1. html, body {
  2. width: 100%;
  3. overflow-x: hidden;
  4. background: #F4F4F4;
  5. font-size: 14px;
  6. color: #555;
  7. }
  8. .container {
  9. margin: 20px auto;
  10. width: 1200px;
  11. overflow: hidden;
  12. }
  13. /*--HEADER--*/
  14. .header {
  15. background: #FFF;
  16. }
  17. .header span {
  18. float: left;
  19. width: 90px;
  20. line-height: 50px;
  21. text-align: center;
  22. }
  23. .header a {
  24. position: relative;
  25. float: left;
  26. padding: 0 15px;
  27. line-height: 50px;
  28. text-align: center;
  29. color: #999;
  30. }
  31. .header a i {
  32. position: absolute;
  33. right: 3px;
  34. top: 50%;
  35. margin-top: -4px;
  36. width: 0;
  37. height: 0;
  38. font-size: 0;
  39. overflow: hidden;
  40. border: 4px solid transparent;
  41. }
  42. .header a i.up {
  43. margin-top: -9px;
  44. border-bottom-color: #999;
  45. }
  46. .header a i.down {
  47. margin-top: 1px;
  48. border-top-color: #999;
  49. }
  50. .header a i.up.bg {
  51. border-bottom-color: #E01D20;
  52. }
  53. .header a i.down.bg {
  54. border-top-color: #E01D20;
  55. }
  56. .header a:hover {
  57. color: #E01D20;
  58. }
  59. /*--LIST--*/
  60. .list {
  61. width: 1205px;
  62. margin-top: 20px;
  63. }
  64. .list li {
  65. margin: 0 10px 10px 0;
  66. float: left;
  67. }
  68. .list li a {
  69. display: block;
  70. padding: 0 16px;
  71. width: 193px;
  72. background: #FFF;
  73. border: 3px solid transparent;
  74. }
  75. .list li a img {
  76. display: block;
  77. width: 100%;
  78. }
  79. .list li a p {
  80. height: 40px;
  81. line-height: 20px;
  82. color: #999;
  83. overflow: hidden;
  84. }
  85. .list li a span {
  86. line-height: 40px;
  87. color: #555;
  88. }
  89. .list li a:hover {
  90. border: 3px solid #E01D20;
  91. }

JS代码

  1. 获取元素对象:
  1. // 获取元素
  2. let headerBox = document.getElementById('header'),
  3. linkList = headerBox.getElementsByTagName('a'),
  4. listBox = document.getElementById('list'),
  5. productList = listBox.getElementsByTagName('li');
  1. 基于ajax获取数据
  1. let productData = null;
  2. let xhr = new XMLHttpRequest(); // 创建一个 ajax 实例对象
  3. xhr.open('GET', 'json/product.json', false); // 调用 xhr 的 open 方法
  4. xhr.onreadystatechange = function () {
  5. // 监听 xhr 的 onreadystatechange 事件
  6. if (xhr.readyState === 4 && xhr.status === 200) {
  7. // 如果满足这个条件,就表示当前请求已经顺利完成
  8. productData = xhr.responseText;
  9. }
  10. };
  11. xhr.send(null); // 发送 ajax 请求
  1. 解析从服务端获取的数据
  1. productData = JSON.parse(productData);
  1. 数据绑定:基于我们从服务端获取的数据,把页面中需要的数据和 html 结构搞出来,最后把数据和 html 添加到页面中的指定容器中。
  1. let str = ``; // 模板字符串
  2. for (let i = 0; i < productData.length; i++) {
  3. let item = productData[i];
  4. // str 在这里还只是一个字符串,不能通过. 属性名的方式自定义属性
  5. str += `<li data-price="${item.price}"
  6. data-time="${item.time}"
  7. data-hot="${item.hot}">
  8. <a href="javascript:;">
  9. <img src="${item.img}" alt="">
  10. <p>${item.title}</p>
  11. <span>¥${item.price}</span> <br>
  12. <span>上架时间:${item.time}</span> <br>
  13. <span>热度:${item.hot}</span>
  14. </a>
  15. </li>`
  16. }
  1. 把拼接好的 html 字符串插入到页面的指定容器中(这些拼接好的字符串在没有添加到页面中,再此之前还不是元素)
  1. listBox.innerHTML = str;
  1. 定义处理排序的方法
  1. let sortList = function (that, index) {
  2. // 用来处理排序逻辑的方法
  3. // 1. 根据 getElementsByTagName 获取的是一个元素集合,而元素集合是一个类数组,如果想调用 sort 进行排序,需要先将类数组转化成数组,数组中 li 并不是克隆出来的,而是原有类数组中元素对象对应的堆内存空间地址。
  4. let productArr = [...productList];
  5. // 2. 基于 sort 按照价格给 li 排序
  6. productArr.sort((a, b) => {
  7. // a 和 b 都是 li 元素对象,所以不能直接相减。
  8. // 我们需要从 li 上面获取到价格
  9. // let innerText = that.innerText;
  10. let aInn, bInn;
  11. let ary = ['data-time', 'data-price', 'data-hot'];
  12. aInn = a.getAttribute(ary[index]);
  13. bInn = b.getAttribute(ary[index]);
  14. let reg = /-/g;
  15. if (index === 0) {
  16. aInn = aInn.replace(reg, '');
  17. bInn = bInn.replace(reg, '')
  18. }
  19. // console.log(aInn, bInn);
  20. return (aInn - bInn) * that.flag; // 排序时使用当前被点击的 a 标签私有的 flag
  21. });
  1. productArr 排好序后页面中并没有按照价格排列,原因是我们还需要把排好序的 li 依次插入到 ul#list(id 为 list 的 ul)中
    for (let i = 0; i < productArr.length; i++) {
    listBox.appendChild(productArr[i]);
    }
    };

7.循环绑定点击事件

  1. for (let i = 0; i < linkList.length; i++) {
  2. linkList[i].flag = -1; // 让每个a标签私有自己的flag,并且在排序时自己管理自己的
  3. linkList[i].onclick = function () {
  4. // 点击价格a标签的时候给li排序
  5. // => 如果你点击某一个a标签的是,想让列表按照当前维度升序排序,就要保证当前a标签的flag是-1;所以我们点击当前a标签的时候,把其他两个a标签的flag重置成-1;
  6. for (let j = 0; j < linkList.length; j++) {
  7. if (linkList[j] !== this) {
  8. // this是当前点击的a标签,!== this就是其他两个
  9. linkList[j].flag = -1; // 重置非当前点击的a标签的flag
  10. }
  11. }
  12. this.flag *= -1; // 给当前点击的a标签上的flag 乘以-1
  13. sortList(this, i);
  14. };
  15. }