博客列表 >一键换肤、购物车自动计算-js-45课8.21

一键换肤、购物车自动计算-js-45课8.21

希望
希望原创
2020年08月29日 14:02:51790浏览

一、一键换肤

1.建demo1.html,引入change-skin.css、change-skin.js

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>换肤</title>
  7. <link rel="stylesheet" href="static/css/change-skin.css" />
  8. </head>
  9. <body>
  10. <div class="container">
  11. <img src="static/images/1.jpg" alt="" />
  12. <img src="static/images/2.jpg" alt="" />
  13. <img src="static/images/3.jpg" alt="" />
  14. </div>
  15. <script src="static/js/change-skin.js"></script>
  16. </body>
  17. </html>

2.change-skin.css

  1. .container {
  2. width: 300px;
  3. display: grid;
  4. grid-template-columns: repeat(3, 1fr);
  5. column-gap: 10px;
  6. }
  7. .container > img {
  8. width: 100%;
  9. border: 3px solid #fff;
  10. opacity: 0.6;
  11. }
  12. .container > img:hover {
  13. opacity: 1;
  14. cursor: pointer;
  15. width: 105%;
  16. }
  17. body {
  18. background-image: url("../images/1.jpg");
  19. background-repeat: no-repeat;
  20. }

3.change-skin.js

  1. // 将当前图片的src赋值给body的背景
  2. // 事件代理
  3. document.querySelector(".container").addEventListener("click", setSkin, false);
  4. function setSkin(ev) {
  5. // ev.target: 事件触发者(img)
  6. // ev.currentTarget: 事件绑定者(.container)
  7. document.body.style.backgroundImage = "url(" + ev.target.src + ")";
  8. }

二、购物车自动计算,共4个文档

1.demo.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>购物车自动计算</title>
  7. <link rel="stylesheet" href="check.css" />
  8. </head>
  9. <body>
  10. <table>
  11. <caption>
  12. 购物车
  13. </caption>
  14. <thead>
  15. <tr>
  16. <th>
  17. <input
  18. type="checkbox"
  19. name="checkAll"
  20. id="check-all"
  21. checked
  22. /><label for="check-all">全选</label>
  23. </th>
  24. <th>ID</th>
  25. <th>品名</th>
  26. <th>单位</th>
  27. <th>单价/元</th>
  28. <th>数量</th>
  29. <th>金额/元</th>
  30. </tr>
  31. </thead>
  32. <tbody>
  33. <tr>
  34. <td>
  35. <input type="checkbox" name="itemId" value="SP-1" />
  36. </td>
  37. <td>SP-1</td>
  38. <td>手机</td>
  39. <td></td>
  40. <td>1899</td>
  41. <td>
  42. <input type="number" name="counter" value="1" min="1" step="1" />
  43. </td>
  44. <td></td>
  45. </tr>
  46. <tr>
  47. <td>
  48. <input type="checkbox" name="itemId" value="SP-2" />
  49. </td>
  50. <td>SP-2</td>
  51. <td>电脑</td>
  52. <td></td>
  53. <td>4999</td>
  54. <td>
  55. <input type="number" name="counter" value="1" min="1" step="1" />
  56. </td>
  57. <td></td>
  58. </tr>
  59. <tr>
  60. <td>
  61. <input type="checkbox" name="itemId" value="SP-3" />
  62. </td>
  63. <td>SP-3</td>
  64. <td>汽车</td>
  65. <td></td>
  66. <td>200000</td>
  67. <td>
  68. <input type="number" name="counter" value="1" min="1" step="1" />
  69. </td>
  70. <td></td>
  71. </tr>
  72. </tbody>
  73. <tfoot>
  74. <tr>
  75. <td colspan="5" style="font-weight: 700;">总计:</td>
  76. <td id="total-num"></td>
  77. <td id="total-price"></td>
  78. </tr>
  79. </tfoot>
  80. </table>
  81. <div style="width: 90%; margin: 10px auto;">
  82. <button style="float: right; width: 100px;">结算</button>
  83. </div>
  84. </td>
  85. </tr>
  86. </tfoot>
  87. </table>
  88. <script src="select.js"></script>
  89. <script src="calculate.js"></script>
  90. </body>
  91. </html>

2.check.css

  1. table {
  2. border-collapse: collapse;
  3. width: 90%;
  4. text-align: center;
  5. margin: auto;
  6. }
  7. table caption {
  8. margin-bottom: 15px;
  9. font-size: 1.5rem;
  10. }
  11. table th,
  12. table td {
  13. border: 1px solid;
  14. padding: 5px;
  15. }
  16. table thead tr:first-of-type {
  17. background-color: lightblue;
  18. }
  19. /* 隔行变色: 偶数行 */
  20. table tbody tr:nth-of-type(even) {
  21. background-color: lightcyan;
  22. }
  23. table input[type="checkbox"] {
  24. width: 20px;
  25. height: 20px;
  26. }
  27. button {
  28. width: 150px;
  29. height: 30px;
  30. outline: none;
  31. border: none;
  32. background-color: seagreen;
  33. color: white;
  34. letter-spacing: 5px;
  35. }
  36. button:hover {
  37. background-color: coral;
  38. cursor: pointer;
  39. }

3.select.js

  1. /** @format */
  2. var selectAllBtn = document.querySelector("#check-all");
  3. //获取每个选项的复选框
  4. var itemBtns = document.querySelectorAll("input[name=itemId]");
  5. //获取所有单价
  6. prices = document.querySelectorAll("table>tbody>tr>td:nth-of-type(5)");
  7. //获取所有商品的数量
  8. numbers = document.querySelectorAll("table>tbody>tr>td>input[type=number]");
  9. // 获取商品单价数组
  10. var unitprice_array = getArrar(prices, "innerText");
  11. // 获取商品数量数组
  12. var counts = getArrar(numbers, "value");
  13. // 获得所有金额
  14. var sumPrices = document.querySelectorAll("tbody > tr > td:nth-of-type(7)");
  15. //初始化 默认为全选状态
  16. init();
  17. function init() {
  18. selectAllBtn.checked = true;
  19. checkAll();
  20. }
  21. //监听全选按钮状态
  22. selectAllBtn.addEventListener("change", checkAll, false);
  23. //添加状态刷新,当全选按钮状态改变时重新渲染页面
  24. selectAllBtn.addEventListener("change", refresh, false);
  25. function refresh() {
  26. autoCalculate();
  27. }
  28. //设置复选框的取消和选中状态并添加默认值
  29. function checkAll() {
  30. itemBtns.forEach(function (btn) {
  31. btn.checked = selectAllBtn.checked;
  32. if (!selectAllBtn.checked) {
  33. btn.parentNode.parentNode.children[5].children.counter.value = 0;
  34. } else {
  35. btn.parentNode.parentNode.children[5].children.counter.value = 1;
  36. }
  37. });
  38. }
  39. itemBtns.forEach(function (btn) {
  40. btn.addEventListener("change", checkAllStatus, false);
  41. });
  42. function checkAllStatus() {
  43. //获取兄弟节点value值,实现取消选中自动重新计算
  44. item_num = this.parentNode.parentNode.querySelector("td>input[type=number]")
  45. .value;
  46. if (this.checked == false && item_num > 0) {
  47. this.parentNode.parentNode.querySelector("td>input[type=number]").value = 0;
  48. } else {
  49. this.parentNode.parentNode.querySelector("td>input[type=number]").value = 1;
  50. }
  51. changeStatus();
  52. autoCalculate();
  53. }
  54. //设置复选框状态
  55. function changeStatus() {
  56. var num = 0;
  57. itemBtns.forEach(function (btn) {
  58. if (btn.checked == true) {
  59. num++;
  60. }
  61. });
  62. // console.log(num);
  63. selectAllBtn.checked = itemBtns.length == num;
  64. }
  65. //将传入伪数组转换为新的数组
  66. function getArrar(array, attr_name) {
  67. return Array.from(array).map((item) => parseInt(item[attr_name]));
  68. }
  69. //每个项目的金额
  70. var amounts = getAmounts(unitprice_array, counts);
  71. //将每个项目的金额渲染到表格中
  72. let subtotal = document.querySelectorAll("tbody>tr>td:last-of-type");
  73. //forEach的第二个参数为当前item的索引
  74. subtotal.forEach((item, index) => (item.innerText = amounts[index]));
  75. //计算每个项目的金额,返回一个新的数组
  76. function getAmounts(unitprice_array, counts) {
  77. let res = [];
  78. for (var i = 0; i < counts.length; i++) {
  79. let amount = unitprice_array[i] * counts[i];
  80. res.push(amount);
  81. }
  82. return res;
  83. }
  84. //计算总金额并渲染到页面
  85. var totalNum = (document.querySelector("#total-num").innerText = getSum(
  86. counts
  87. ));
  88. var totalAmount = (document.querySelector("#total-price").innerText = getSum(
  89. amounts
  90. ));
  91. //使用reduce方法计算数组每项的和
  92. function getSum(array) {
  93. return array.reduce((total, num) => total + num, 0);
  94. }
  95. //为数量控件添加change事件
  96. numbers.forEach((item) => item.addEventListener("input", autoCalculate));
  97. numbers.forEach((item) => item.addEventListener("input", autoSelect));
  98. //当input[type=number]值改变时设置复选框选中,重新计算金额
  99. function autoSelect() {
  100. this.parentNode.parentNode.querySelector(
  101. "td>input[name=itemId]"
  102. ).checked = true;
  103. // 重新计算所有被选中复选框的数量
  104. changeStatus();
  105. }
  106. //自动计算函数
  107. function autoCalculate() {
  108. counts = getArrar(numbers, "value");
  109. amounts = getAmounts(unitprice_array, counts);
  110. subtotal.forEach((item, index) => (item.innerText = amounts[index]));
  111. totalNum = document.querySelector("#total-num").innerText = getSum(counts);
  112. totalAmount = document.querySelector("#total-price").innerText = getSum(
  113. amounts
  114. );
  115. }

4.calculate.js

  1. // 商品数量: 数组
  2. var counts = [];
  3. // 商品金额: 数组
  4. var amounts = [];
  5. // 商品单价: 数组
  6. var unitPrices = [];
  7. // 商品总数量
  8. var totalNum = 0;
  9. // 商品总金额
  10. var totalAmount = 0;
  11. // 获取商品数量控件<input:number>
  12. var numbers = document.querySelectorAll("input[type=number]");
  13. // 获取所有商品单价
  14. var prices = document.querySelectorAll("tbody > tr > td:nth-of-type(5)");
  15. // 1. 生成商品数量: 数组
  16. counts = getCounts(numbers);
  17. function getCounts(numbers) {
  18. // Array.from(numbers): 将类数组,转为真正数组
  19. // map()与forEach()功能相同, 只不过他返回一个新数组
  20. return Array.from(numbers).map(function (item) {
  21. return parseInt(item.value);
  22. });
  23. }
  24. console.log(counts);
  25. // 2. 商品单价: 数组
  26. unitPrices = getUnitPrices(prices);
  27. function getUnitPrices(prices) {
  28. return Array.from(prices).map(function (item) {
  29. // 拿到里面文本的值innerText
  30. return parseInt(item.innerText);
  31. });
  32. }
  33. console.log(unitPrices);
  34. // 3. 计算每个商品的金额之和
  35. amounts = getEveryAmount(counts, unitPrices);
  36. function getEveryAmount(counts, unitPrices) {
  37. var result = [];
  38. for (var i = 0; i < unitPrices.length; i++) {
  39. // 金额 = 单价 * 数量
  40. amount = unitPrices[i] * counts[i];
  41. // 将这个商品金额添加到金额数组中
  42. result.push(amount);
  43. }
  44. return result;
  45. }
  46. console.log(amounts);
  47. // 将每个商品金额渲染到页面中
  48. var subtotal = document.querySelectorAll("tbody > tr > td:last-of-type");
  49. // forEach(function (value,[ key, array]))
  50. subtotal.forEach(function (sub, index) {
  51. sub.innerHTML = amounts[index];
  52. });
  53. // 4. 计算数量总和
  54. totalNum = numTotal(counts);
  55. // reduce()归并,最终将所有数组元素累加成一个值返回
  56. function numTotal(counts) {
  57. return counts.reduce(function (prev, next) {
  58. // 累加
  59. return (prev += next);
  60. }, 0);
  61. }
  62. console.log(totalNum);
  63. // 将数量之和添加到页面中
  64. document.getElementById("total-num").innerText = totalNum;
  65. // 5 计算所有商品总金额
  66. totalAmount = getTotalAmount(amounts);
  67. function getTotalAmount(amounts) {
  68. return amounts.reduce(function (prev, next) {
  69. return (prev += next);
  70. }, 0);
  71. }
  72. console.log(totalAmount);
  73. // 将总金额添加到页面中
  74. document.getElementById("total-price").innerText = totalAmount;
  75. // 6. 给每个数量控件添加change事件
  76. numbers.forEach(function (item) {
  77. item.addEventListener("change", autoCalculate, false);
  78. });
  79. function autoCalculate(ev) {
  80. // 更新总数量
  81. counts = getCounts(numbers);
  82. totalNum = numTotal(counts);
  83. document.getElementById("total-num").innerText = totalNum;
  84. // 更新每件商品的金额
  85. var subtotal = document.querySelectorAll("tbody > tr > td:last-of-type");
  86. subtotal.forEach(function (sub, index) {
  87. sub.innerHTML = amounts[index];
  88. });
  89. // 每个商品的金额之和
  90. amounts = getEveryAmount(counts, unitPrices);
  91. // 更新总金额
  92. totalAmount = getTotalAmount(amounts);
  93. document.getElementById("total-price").innerText = totalAmount;
  94. }

  • 总结:
  • 横向计算商品数量*单价,得到一种商品总金额
  • 竖向计算所有商品总数量和总金额
  • 添加数量增加的事件,更新总数量,总金额到页面中去
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议