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

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

超超多喝水
超超多喝水原创
2021年11月11日 01:17:51739浏览

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

标签切换

  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>
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议