欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

标签切换、轮播图及购物车小案例相关知识总结

程序员文章站 2022-03-13 12:40:47
...

标签切换、图片墙调整、轮播图及购物车小案例相关知识总结

标签切换

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <link rel="stylesheet" href="style.css" />
  8. <title>选项卡</title>
  9. </head>
  10. <body>
  11. <div class="tabs">
  12. <!-- 导航 -->
  13. <!-- <ul class="tab" onclick="show(event)"> -->
  14. <ul class="tab" onmouseover="show(event)">
  15. <!-- data-index: 自定义属性,用dataset来读写 -->
  16. <li class="active" data-index="1">娱乐</li>
  17. <li data-index="2">科技</li>
  18. <li data-index="3">军事</li>
  19. </ul>
  20. <!-- 与导航对应的相应用列表,有几个导航就应该有几个列表 -->
  21. <ul data-index="1" class="item active">
  22. <li><a href="">这个国庆档,吴京离“封神”又近了一步</a></li>
  23. <li><a href="">这个国庆档,吴京离“封神”又近了一步</a></li>
  24. <li><a href="">这个国庆档,吴京离“封神”又近了一步</a></li>
  25. <li><a href="">这个国庆档,吴京离“封神”又近了一步</a></li>
  26. <li><a href="">这个国庆档,吴京离“封神”又近了一步</a></li>
  27. </ul>
  28. <ul data-index="2" class="item">
  29. <li><a href="">腾讯全面支持银联云闪付,支付宝还会远吗</a></li>
  30. <li><a href="">腾讯全面支持银联云闪付 支付宝还会远吗</a></li>
  31. <li><a href="">腾讯全面支持银联云闪付 支付宝还会远吗</a></li>
  32. <li><a href="">腾讯全面支持银联云闪付 支付宝还会远吗</a></li>
  33. <li><a href="">腾讯全面支持银联云闪付 支付宝还会远吗</a></li>
  34. </ul>
  35. <ul data-index="3" class="item">
  36. <li><a href="">华为汽车: 带着"极狐" 的销量走来了?</a></li>
  37. <li><a href="">华为汽车: 带着"极狐" 的销量走来了?</a></li>
  38. <li><a href="">华为汽车: 带着"极狐" 的销量走来了?</a></li>
  39. <li><a href="">华为汽车: 带着"极狐" 的销量走来了?</a></li>
  40. <li><a href="">华为汽车: 带着"极狐" 的销量走来了?</a></li>
  41. </ul>
  42. </div>
  43. <script>
  44. //数组.filter()数组过滤器
  45. let arr = [3, 4, 5, 72, 35, 7, 8, 95, 5, 7, 8, 34, 10];
  46. //filter前面加数组,括号内是箭头函数
  47. let res = arr.filter((item) => item >= 5);
  48. console.log(res);
  49. //给上导航绑定点击事件
  50. //函数的形参跟实参是事件
  51. function show(ev) {
  52. //获取事件绑定者
  53. console.log(ev.currentTarget);
  54. //获取事件触发者
  55. console.log(ev.target);
  56. //赋值给变量
  57. const ul = ev.currentTarget;
  58. const li = ev.target;
  59. //循环遍历li,取消之前已经添加的active
  60. // const lis = document.querySelectorAll(".tabs>.tab>li");
  61. // for (let i = 0; i < lis.length; i++) {
  62. // if (lis[i].className === "active") {
  63. // lis[i].classList.remove("active");
  64. // }
  65. // }
  66. [...ul.children].forEach((item) => item.classList.remove("active"));
  67. //给li动态添加class类
  68. li.classList.add("active");
  69. const uls = [...document.querySelectorAll(".tabs>.item")];
  70. uls.forEach((item) => item.classList.remove("active"));
  71. //这里获取的还是数组,后面加个索引0
  72. uls.filter((item) => item.dataset.index === li.dataset.index)[0].classList.add("active");
  73. }
  74. </script>
  75. </body>
  76. </html>

图片墙调整

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <link rel="stylesheet" href="style.css" />
  8. <title>在线相册</title>
  9. </head>
  10. <body>
  11. <ul class="container"></ul>
  12. <script>
  13. //array.reduce():数组的归并函数
  14. //array.reduce(function(起始值(如果不自定义起始值,则默认是数组的第一个值),起始值的下一个值){},起始值(可以是任意值));
  15. // let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  16. // arr.reduce(function (prev, cur) {
  17. // console.log(prev, cur);
  18. // return prev + cur;
  19. // }, 11);
  20. let imgS = [
  21. "images/img_1.jpg",
  22. "images/img_2.jpg",
  23. "images/img_3.jpg",
  24. "images/img_4.jpg",
  25. "images/img_5.jpg",
  26. "images/img_6.jpg",
  27. "images/img_7.jpg",
  28. "images/img_8.jpg",
  29. ];
  30. const ul = document.querySelector(".container");
  31. window.onload = showImages();
  32. function showImages() {
  33. let res = imgS.reduce(function (prev, cur) {
  34. let tpl = `
  35. <li>
  36. <img src="${cur}"/>
  37. <div>
  38. <button onclick=prev(this.parentNode.parentNode)>向前</button>
  39. <button onclick=next(this.parentNode.parentNode)>向后</button>
  40. <button onclick=del(this.parentNode.parentNode)>删除</button>
  41. </div>
  42. </li>
  43. `;
  44. return prev + tpl;
  45. //前面得加个空字符串,要不默认数组是第一个开始,这里添加的却是当前,会导致第一个没有li跟img标签的
  46. }, "");
  47. // console.log(res);
  48. ul.insertAdjacentHTML("afterbegin", res);
  49. }
  50. //confirm()弹出对话框确认为真取消为假
  51. function del(ele) {
  52. return confirm("你要毁掉我的老婆??") ? ele.remove() : false;
  53. }
  54. //parent.insertBefore(要插入的子元素,插入的子元素的位置),insertBefore前面必须是父元素
  55. // previousSibling 属性返回元素节点之前的兄弟节点(包括文本节点、注释节点);
  56. // previousElementSibling 属性只返回元素节点之前的兄弟元素节点(不包括文本节点、注释节点);
  57. function prev(ele) {
  58. let prevNode = ele.previousElementSibling;
  59. if (prevNode === null) {
  60. alert("已经是大老婆了");
  61. return false;
  62. } else {
  63. ul.insertBefore(ele, prevNode);
  64. }
  65. }
  66. function next(ele) {
  67. let nextNode = ele.nextElementSibling;
  68. if (nextNode === null) {
  69. alert("已经打入冷宫了");
  70. return false;
  71. } else {
  72. ul.insertBefore(nextNode, ele);
  73. }
  74. }
  75. </script>
  76. </body>
  77. </html>

轮播图

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>轮播图</title>
  8. <link rel="stylesheet" href="style.css" />
  9. </head>
  10. <body>
  11. <!-- 容器区域 -->
  12. <div class="container">
  13. <!-- 图片组 -->
  14. <div class="img-group"></div>
  15. <!-- 翻页组 -->
  16. <div class="skip">
  17. <a class="prev" href="" onclick="prevImg(event)">&lt;</a>
  18. <!-- 禁用a标签默认行为方法1 -->
  19. <!-- <a class="prev" href="javascript:;" onclick="prevImg(event)">&lt;</a> -->
  20. <a class="next" href="" onclick="nextImg(event)">&gt;</a>
  21. </div>
  22. <!-- 按钮组 -->
  23. <div class="btn-group"></div>
  24. </div>
  25. <script>
  26. //图片
  27. const images = ["images/banner_1.jpg", "images/banner_2.jpg", "images/banner_3.jpg", "images/banner_4.jpg"];
  28. const imgGroup = document.querySelector(".img-group");
  29. //按钮
  30. const btnGroup = document.querySelector(".btn-group");
  31. window.onload = () => {
  32. createImages(imgGroup, images.length);
  33. createBtns(btnGroup, images.length);
  34. //页面加载完成后自动调用一次自动循环
  35. autoStart(event);
  36. };
  37. function createImages(parent, length) {
  38. //创建虚拟节点对象,减少页面渲染抖动
  39. const frag = document.createDocumentFragment();
  40. for (let i = 0; i < length; i++) {
  41. //这个img必须在for循环里面,这样才能每次都生成一个img,放到外面只能每次都更新里面的属性
  42. const img = document.createElement("img");
  43. img.src = images[i];
  44. img.alt = `banner${i + 1}`;
  45. img.dataset.index = `${i + 1}`;
  46. if (i === 0) img.classList.add("active");
  47. frag.append(img);
  48. }
  49. //将虚拟节点对象的子孙节点全部插入到parent中
  50. parent.append(frag);
  51. }
  52. function createBtns(parent, length) {
  53. //创建虚拟节点对象,减少页面渲染抖动
  54. const frag = document.createDocumentFragment();
  55. for (let i = 0; i < length; i++) {
  56. const span = document.createElement("span");
  57. span.dataset.index = `${i + 1}`;
  58. // 给span按钮添加点击事件
  59. if (i === 0) span.classList.add("active");
  60. //这里跟html中不同 changeImg后面不需要加括号
  61. //加上括号是执行的意思,添加事件的回调函数应该就是给相应的事件属性赋值,而很明显需要把一个函数赋值给这个事件属性,
  62. //而不是函数的调用结果。所以在js中的绑定是直接赋值。而在标签内的事件属性的值是由引号包裹的,代表的是当点击该元素时,执行引号内的代码,直接把引号内的代码拿出来跑,如果你不加括号,那就不会调用那个函数。
  63. span.onclick = changeImg;
  64. frag.append(span);
  65. }
  66. //
  67. //将虚拟节点对象的子孙节点全部插入到parent中
  68. parent.append(frag);
  69. }
  70. //图片切页小按钮
  71. function changeImg(ev) {
  72. const span = btnGroup.querySelectorAll("span");
  73. const img = imgGroup.querySelectorAll("img");
  74. // console.log(img);
  75. // console.log(ev.target);
  76. // for (let i = 0; i < img.length; i++) {
  77. // span[i].classList.remove("active");
  78. // img[i].classList.remove("active");
  79. // }
  80. // forEach简写
  81. [span, img].forEach((items) => {
  82. //二次遍历
  83. items.forEach((item) => {
  84. //判断带active的取消,不带的不管
  85. if (item.classList.contains("active")) item.classList.remove("active");
  86. });
  87. });
  88. ev.target.classList.add("active");
  89. img.forEach((item) => {
  90. if (item.dataset.index === ev.target.dataset.index) item.classList.add("active");
  91. });
  92. }
  93. //前翻页
  94. function prevImg(ev) {
  95. // 禁用a标签默认行为方法二
  96. ev.preventDefault();
  97. //拿到当前带active类的按钮跟图片
  98. const span = btnGroup.querySelector("span.active");
  99. const img = imgGroup.querySelector("img.active");
  100. //拿到当前带active类的按钮跟图片的对应的前一个兄弟元素
  101. const spanPrev = span.previousElementSibling;
  102. const imgPrev = img.previousElementSibling;
  103. span.classList.remove("active");
  104. img.classList.remove("active");
  105. if (spanPrev !== null && imgPrev !== null) {
  106. spanPrev.classList.add("active");
  107. imgPrev.classList.add("active");
  108. } else {
  109. btnGroup.lastElementChild.classList.add("active");
  110. imgGroup.lastElementChild.classList.add("active");
  111. }
  112. }
  113. //后翻页
  114. function nextImg(ev) {
  115. // 禁用a标签默认行为方法二
  116. ev.preventDefault();
  117. //拿到当前带active类的按钮跟图片
  118. const span = btnGroup.querySelector("span.active");
  119. const img = imgGroup.querySelector("img.active");
  120. //拿到当前带active类的按钮跟图片的对应的前一个兄弟元素
  121. const spanNext = span.nextElementSibling;
  122. const imgNext = img.nextElementSibling;
  123. span.classList.remove("active");
  124. img.classList.remove("active");
  125. if (spanNext !== null && imgNext !== null) {
  126. spanNext.classList.add("active");
  127. imgNext.classList.add("active");
  128. } else {
  129. btnGroup.firstElementChild.classList.add("active");
  130. imgGroup.firstElementChild.classList.add("active");
  131. }
  132. }
  133. // 初步自动播放
  134. // const next = document.querySelector(".container>.skip>.next");
  135. // const autoClick = new Event("click");
  136. // setInterval(() => next.dispatchEvent(autoClick), 2000);
  137. //加入限制,这里需要注意setInterval()如果需要停止,那么得把它赋值给一个变量,到时候停止这个同名变量
  138. let time = null;
  139. const next = document.querySelector(".container>.skip>.next");
  140. const container = document.querySelector(".container");
  141. const autoClick = new Event("click");
  142. container.addEventListener("mouseover", autoStop);
  143. container.addEventListener("mouseout", autoStart);
  144. // container.onmouseover = autoStop;
  145. // container.onmouseout = autoStart;
  146. function autoStart() {
  147. time = setInterval(() => next.dispatchEvent(autoClick), 2000);
  148. }
  149. function autoStop() {
  150. clearInterval(time);
  151. }
  152. </script>
  153. </body>
  154. </html>

购物车

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <link rel="stylesheet" href="style.css" />
  8. <title>购物车</title>
  9. </head>
  10. <body>
  11. <table>
  12. <caption>
  13. 我的购物车
  14. </caption>
  15. <thead>
  16. <th><input type="checkbox" name="checkAll" id="check-all" checked /><label for="check-all">全选</label></th>
  17. <th>图片</th>
  18. <th>品名</th>
  19. <th>单位</th>
  20. <th>单价/元</th>
  21. <th>数量</th>
  22. <th>金额/元</th>
  23. </thead>
  24. <tbody>
  25. <tr>
  26. <td>
  27. <input type="checkbox" name="item" class="item" value="SN-1020" checked />
  28. </td>
  29. <td>
  30. <a href=""><img src="images/p1.png" alt="" /></a>
  31. </td>
  32. <td>JavaScript权威指南(第七版)</td>
  33. <td></td>
  34. <td class="price">100</td>
  35. <td>
  36. <input type="number" min="1" value="1" />
  37. </td>
  38. <td class="amount">0</td>
  39. </tr>
  40. <tr>
  41. <td>
  42. <input type="checkbox" name="item" class="item" value="SN-1020" checked />
  43. </td>
  44. <td>
  45. <a href=""><img src="images/p2.png" alt="" /></a>
  46. </td>
  47. <td>JavaScript高级程序设计(第四版)</td>
  48. <td></td>
  49. <td class="price">129</td>
  50. <td>
  51. <input type="number" min="1" value="1" />
  52. </td>
  53. <td class="amount">0</td>
  54. </tr>
  55. <tr>
  56. <td>
  57. <input type="checkbox" name="item" class="item" value="SN-1030" checked />
  58. </td>
  59. <td>
  60. <a href=""><img src="images/p3.png" alt="" /></a>
  61. </td>
  62. <td>JavaScript忍者秘籍(第二版)</td>
  63. <td></td>
  64. <td class="price">99</td>
  65. <td>
  66. <input type="number" min="1" value="1" />
  67. </td>
  68. <td class="amount">0</td>
  69. </tr>
  70. <tr>
  71. <td>
  72. <input type="checkbox" name="item" class="item" value="SN-1040" checked />
  73. </td>
  74. <td>
  75. <a href=""><img src="images/p4.png" alt="" /></a>
  76. </td>
  77. <td>ThinkPad X1 Carbon 2021</td>
  78. <td></td>
  79. <td class="price">12999</td>
  80. <td>
  81. <input type="number" min="1" value="1" />
  82. </td>
  83. <td class="amount">0</td>
  84. </tr>
  85. <tr>
  86. <td>
  87. <input type="checkbox" name="item" class="item" value="SN-1050" checked />
  88. </td>
  89. <td>
  90. <a href=""><img src="images/p5.png" alt="" /></a>
  91. </td>
  92. <td>MacBook Pro 16 10代i7 16G 512G</td>
  93. <td></td>
  94. <td class="price">23800</td>
  95. <td>
  96. <input type="number" min="1" value="1" />
  97. </td>
  98. <td class="amount">0</td>
  99. </tr>
  100. </tbody>
  101. <tfoot>
  102. <tr>
  103. <td colspan="5">总计:</td>
  104. <td id="sum">0</td>
  105. <td id="total-amount">0</td>
  106. </tr>
  107. </tfoot>
  108. </table>
  109. <div style="width: 90%; margin: 10px auto">
  110. <button style="float: right; width: 100px">结算</button>
  111. </div>
  112. <script>
  113. // let arr = [3, 4, 5, 6, 7, 8];
  114. // console.log(arr.some((item) => item > 4));
  115. // console.log(arr.every((item) => item > 4));
  116. // onchange
  117. const checkAll = document.getElementById("check-all");
  118. const items = document.getElementsByName("item");
  119. checkAll.onchange = function (ev) {
  120. //首先配置下面商品的选择跟随上面全选按钮进行全选或全不选,下面跟随上面的状态,这里不能设置true,设置true就不管咋点都是全选
  121. items.forEach((item) => (item.checked = ev.target.checked));
  122. };
  123. //配置有一个按钮没选中全选失效,全部选中全选生效
  124. // items.forEach(function (item) {
  125. // item.onchange = function (ev) {
  126. // if ([...items].some((item) => item.checked == false)) {
  127. // checkAll.checked = false;
  128. // } else if ([...items].every((item) => item.checked == true)) {
  129. // checkAll.checked = true;
  130. // }
  131. // };
  132. // });
  133. //不用这么复杂,只需要先遍历一遍下面的小按钮,当小按钮点击的时候触发一个onchange,函数对象中直接用array.every作判断给checkAll的checked属性赋值true or false就可以啊
  134. items.forEach(function (item) {
  135. item.onchange = function () {
  136. checkAll.checked = [...items].every((item) => item.checked);
  137. };
  138. });
  139. //方法一:
  140. // const price = document.querySelectorAll(".price");
  141. // const number = document.querySelectorAll("input[type='number']");
  142. // const amount = document.querySelectorAll(".amount");
  143. // const sum = document.getElementById("sum");
  144. // const totalAmount = document.getElementById("total-amount");
  145. // let myChange = new Event("change");
  146. // for (let i = 0; i < [...price].length; i++) {
  147. // number[i].onchange = getPrice;
  148. // number[i].onkeyup = getPrice;
  149. // number[i].afterpaste = getPrice;
  150. // items[i].onchange = getPrice;
  151. // number[i].dispatchEvent(myChange);
  152. // }
  153. // function getPrice() {
  154. // let s = 0;
  155. // let t = 0;
  156. // for (let i = 0; i < [...price].length; i++) {
  157. // if (number[i].value == "") {
  158. // number[i].value = 0;
  159. // } else {
  160. // if (typeof number[i].value !== "number" || number[i].value % 1 !== 0) number[i].value = parseInt(number[i].value);
  161. // }
  162. // amount[i].innerText = price[i].innerText * number[i].value;
  163. // if (items[i].checked === false) {
  164. // s += 0;
  165. // t += 0;
  166. // } else {
  167. // s += parseInt(number[i].value);
  168. // t += parseInt(amount[i].innerText);
  169. // }
  170. // }
  171. // sum.innerText = s;
  172. // totalAmount.innerText = t;
  173. // }
  174. //方法二:
  175. //获取数量
  176. const number = document.querySelectorAll("input[type='number']");
  177. //给每个数量加监听事件
  178. [items, number].forEach((items) =>
  179. items.forEach((item) => {
  180. item.onchange = getPrice;
  181. item.onkeyup = getPrice;
  182. item.afterpaste = getPrice;
  183. })
  184. );
  185. function getPrice() {
  186. //获取数量
  187. const number = document.querySelectorAll("input[type='number']");
  188. //这里的num是number类型的input元素啊,别忘了加value,用map函数遍历成新的数组,×1使数据类型变为数值
  189. // [...number].forEach((num) => (num.value = parseInt(num.value)));
  190. //数量这里用parseInt()强制转换成了整型
  191. const numArr = [...number].map((num) => (num.value = parseInt(num.value)));
  192. //获取单价
  193. const price = document.querySelectorAll(".price");
  194. const priceArr = [...price].map((price) => (price.textContent = price.textContent * 1));
  195. //遍历出每一个的单条总价(显示用)
  196. const amountArrA = [numArr, priceArr].reduce((prev, cur) => prev.map((val, key) => val * cur[key]));
  197. //遍历item的checked属性做个判断,判断为真时保留数值,为假时数量赋值0
  198. items.forEach((item, key) => {
  199. if (!item.checked) numArr[key] = 0;
  200. });
  201. //遍历出每一个的单条总价(计算用)
  202. const amountArrC = [numArr, priceArr].reduce((prev, cur) => prev.map((val, key) => val * cur[key]));
  203. // console.log(amountArr);
  204. //总数
  205. const nubSum = numArr.reduce((prev, cur) => prev + cur);
  206. //总价
  207. const priceSum = amountArrC.reduce((prev, cur) => prev + cur);
  208. const amount = document.querySelectorAll(".amount");
  209. const sum = document.getElementById("sum");
  210. const totalAmount = document.getElementById("total-amount");
  211. //加入页面
  212. amount.forEach((item, index) => (item.textContent = amountArrA[index]));
  213. sum.textContent = nubSum;
  214. totalAmount.textContent = priceSum;
  215. }
  216. window.onload = function () {
  217. getPrice();
  218. };
  219. </script>
  220. </body>
  221. </html>