ASCII码 ASCII码

js实战:选项卡、购物车、轮播图、懒加载效果

发布于:2022-02-09 10:20:29  栏目:技术文档

1. 实例演示选项卡功能

  1. <!DOCTYPE html>
  2. <html lang="en">
  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. </head>
  9. <body>
  10. <style>
  11. .tabs {
  12. width: 12em;
  13. display: grid;
  14. grid-template-columns: repeat(3, 1fr);
  15. }
  16. .tabs li {
  17. list-style: none;
  18. padding: 0.5em 1em;
  19. }
  20. .tabs li:hover {
  21. cursor: pointer;
  22. }
  23. .content {
  24. display: none;
  25. }
  26. .tabs .active {
  27. background-color: cyan;
  28. }
  29. .content.active {
  30. display: block;
  31. }
  32. </style>
  33. <div class="box">
  34. <!-- 选项卡 -->
  35. <!-- 利用冒泡只需在ul设置事件 -->
  36. <ul class="tabs" onclick="show()">
  37. <!-- 每个列表加自定义属性,记录序号,点击后验证是点哪个列表,显示对应的内容 -->
  38. <li data-index="1" class="active">体育</li>
  39. <li data-index="2">科技</li>
  40. <li data-index="3">探索</li>
  41. </ul>
  42. <!-- 体育选项卡内容 -->
  43. <ul class="content active" data-index="1">
  44. <li><a href="">12强赛-国足0-2完败日本 7战5分出线希望愈发渺茫</a></li>
  45. <li><a href="">王燊超封堵时手触球送点 越南队7战0分提前出局</a></li>
  46. <li><a href="">国足官方宣布郭田雨留洋 朱艺:维泽拉最高中锋仅1米</a></li>
  47. <li><a href="">巴萨起诉前任主席巴托梅乌 经纪人表态登贝莱愿留队</a></li>
  48. <li><a href="">李雯雯:回家过年因8点起床挨骂</a></li>
  49. </ul>
  50. <!-- 科技选项卡内容 -->
  51. <ul class="content" data-index="2">
  52. <li><a href="">腾讯申请微信键盘商标被驳回</a></li>
  53. <li><a href="">高途教育经营新增职业中介活动</a></li>
  54. <li><a href="">美国加州将为工人延长带薪病假</a></li>
  55. <li><a href="">证监会坐实零跑汽车境外IPO传闻</a></li>
  56. <li><a href="">常规电视剧剧集正片时长不能少于41分</a></li>
  57. </ul>
  58. <!-- 探索选项卡内容 -->
  59. <ul class="content" data-index="3">
  60. <li><a href="">这场大火已经燃烧了6000年</a></li>
  61. <li><a href="">为什么电流会有嗡嗡响怪声音?</a></li>
  62. <li><a href="">为什么说人类正输给超级细菌?</a></li>
  63. <li><a href="">它一生可能只活5年,3.75年都在睡觉!</a></li>
  64. <li><a href="">汤加火山爆发在地球另一端引发海啸</a></li>
  65. </ul>
  66. </div>
  67. <script>
  68. function show() {
  69. // 1. 选项卡切换效果
  70. // 使用event.currentTarget获取事件绑定元素,即ul,包含li
  71. // 使用...转为数组,forEach方法遍历li元素,移除active样式
  72. [...event.currentTarget.children].forEach((li) =>
  73. li.classList.remove("active")
  74. );
  75. // 当前点击的标签加active样式
  76. // 用event.target获取事件触发元素
  77. event.target.classList.add("active");
  78. // 2.内容显示效果
  79. // 移除当前显示内容的active样式
  80. // 方法同选项卡,用遍历
  81. document
  82. .querySelectorAll(".content")
  83. .forEach((li) => li.classList.remove("active"));
  84. // 显示自定义属性相同的内容
  85. [...document.querySelectorAll(".content")]
  86. .find((ul) => ul.dataset.index === event.target.dataset.index)
  87. .classList.add("active");
  88. }
  89. </script>
  90. </body>
  91. </html>

2. 购物车

  1. <!DOCTYPE html>
  2. <html lang="en">
  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. </head>
  9. <body>
  10. <style>
  11. .selectAll {
  12. margin-top: 1em;
  13. margin-left: 0.7em;
  14. }
  15. .selectAll *:hover {
  16. cursor: pointer;
  17. }
  18. .shopingList {
  19. padding: 0;
  20. width: 35em;
  21. background-color: lightskyblue;
  22. }
  23. .shopingList > li {
  24. width: 35em;
  25. display: grid;
  26. grid-template-columns: 3.5em repeat(5, 5fr);
  27. border-bottom: 1px solid rgb(12, 63, 105);
  28. }
  29. .shopingList > li:nth-of-type(1) {
  30. color: #eee;
  31. background-color: rgb(12, 63, 105);
  32. }
  33. li:last-of-type span:nth-of-type(1) {
  34. text-align: center;
  35. grid-column: 1 / span 5;
  36. }
  37. li:nth-of-type(n + 2):hover,
  38. li input[type="checkbox"] {
  39. cursor: pointer;
  40. background-color: rgb(135, 194, 250);
  41. }
  42. h4,
  43. span {
  44. margin: 0.2em 0.6em;
  45. }
  46. h4 {
  47. padding: 0.3em 0;
  48. }
  49. input[type="number"] {
  50. width: 70%;
  51. outline: none;
  52. }
  53. </style>
  54. <div class="box">
  55. <!-- 全选框 -->
  56. <div class="selectAll">
  57. <input
  58. type="checkbox"
  59. onchange="checkAll(),autoCount()"
  60. name="check-all"
  61. id="check-all"
  62. />
  63. <label for="check-all">全选</label>
  64. </div>
  65. <ul class="shopingList">
  66. <li>
  67. <h4>选择</h4>
  68. <h4>品名</h4>
  69. <h4>数量</h4>
  70. <h4>单位</h4>
  71. <h4>单价(元)</h4>
  72. <h4>金额(元)</h4>
  73. </li>
  74. <li>
  75. <span><input type="checkbox" /> </span>
  76. <span>土豆</span>
  77. <span><input type="number" value="1" min="1" class="num" /></span>
  78. <span>斤</span>
  79. <span class="price">3.5</span>
  80. <span class="amount">0</span>
  81. </li>
  82. <li>
  83. <span><input type="checkbox" /> </span>
  84. <span>土猪肉</span>
  85. <span><input type="number" value="1" min="1" class="num" /></span>
  86. <span>斤</span>
  87. <span class="price">24</span>
  88. <span class="amount">0</span>
  89. </li>
  90. <li>
  91. <span><input type="checkbox" /> </span>
  92. <span>啤酒</span>
  93. <span><input type="number" value="1" min="1" class="num" /></span>
  94. <span>瓶</span>
  95. <span class="price">6.8</span>
  96. <span class="amount">0</span>
  97. </li>
  98. <li>
  99. <span>合计</span>
  100. <span class="total-amount">2</span>
  101. </li>
  102. </ul>
  103. </div>
  104. </body>
  105. <script>
  106. // 1. 实现全选功能
  107. function checkAll() {
  108. // 获取触发事件的选择框状态;
  109. let checkbox_status = event.target.checked;
  110. // 定义数组,获取所有商品选择框元素
  111. const checkbox_goods = document.querySelectorAll(
  112. ".shopingList input[type=checkbox]"
  113. );
  114. // 遍历商品选择框数组设为选择状态
  115. checkbox_goods.forEach((i) => (i.checked = checkbox_status));
  116. }
  117. // 2. 根据每个商品选择状态来设置全选;
  118. function checkbox() {
  119. // 获取所有商品的选择框元素;
  120. const checkbox_goods = document.querySelectorAll(
  121. ".shopingList input[type=checkbox]"
  122. );
  123. // 用数组的every方法判断所有选择框是否全是选中状态,返回true,定义变量存放
  124. // 此处要注意,checkbox_goods不是数组,用...转为数组
  125. let checkbox_goods_status = [...checkbox_goods].every(
  126. (i) => i.checked === true
  127. );
  128. // 给全选框赋值
  129. document.querySelector("#check-all").checked = checkbox_goods_status;
  130. }
  131. // 3. 商品的自动计算
  132. // 单个商品的计算基于数量改变
  133. // 合计计算基于所选择的商品
  134. // 思路:先定义计算单个商品、计算合计两个函数
  135. // 定义自动计算单个商品函数
  136. // 定义自动计算合计函数
  137. // 打开购物车时,判断勾选调用自动计算
  138. // 商品数量变化时,判断勾选调用自动计算
  139. // 勾选变化时调用自动计算
  140. // 定义数组常量:记录商品数量元素。考虑后面要给每个元素加商品数量改变事件。
  141. const input_nums = document.querySelectorAll(".num");
  142. // 计算每个商品的金额函数:参数为数量数组,单价数组
  143. function singleAmount(numArr, priceArr) {
  144. // 用数组函数map遍历数量数组numArr计算金额
  145. return numArr.map(
  146. (goods_num, num_index) =>
  147. parseFloat(goods_num) * parseFloat(priceArr[num_index])
  148. );
  149. }
  150. // 计算合计金额的函数:参数为每个商品金额数组
  151. function totalAmount(amountArr) {
  152. // 用数组函数reduce遍历金额数组累加
  153. return amountArr.reduce((total_value, amount) => total_value + amount);
  154. }
  155. // 自动计算函数
  156. function autoCount() {
  157. // 获取商品数量数组:数量元素转为数组,map遍历,再取每个元素的值
  158. const goods_nums_Arr = [...input_nums].map(
  159. (input_num) => input_num.value
  160. );
  161. // 获取商品单价元素
  162. const prices_elements = document.querySelectorAll(".price");
  163. // 商品单价数组:方法同上,取每个元素的文字内容,用parseFloat函数转为浮点数字
  164. const goods_price_Arr = [...prices_elements].map((prices_element) =>
  165. parseFloat(prices_element.textContent)
  166. );
  167. // 每个商品金额数组
  168. const goods_single_amount_Arr = singleAmount(
  169. goods_nums_Arr,
  170. goods_price_Arr
  171. );
  172. // 获取每个商品全额元素,遍历每个元素,元素的文字内容设置为对应索引金额
  173. document
  174. .querySelectorAll(".amount")
  175. .forEach(
  176. (amount_element, index) =>
  177. (amount_element.textContent = goods_single_amount_Arr[index])
  178. );
  179. // 获取选择框元素
  180. const checked_elementArr = [
  181. ...document.querySelectorAll(".shopingList input[type=checkbox]"),
  182. ];
  183. // 定义要统计合计的金额数组
  184. let count_goods_single_amount_Arr = [];
  185. // 定义合计元素变量
  186. const total_amount_element = document.querySelector(".total-amount");
  187. // 遍历选择框元素,勾选的,通过索引获取对应商品金额数组的数值组成新数组
  188. checked_elementArr.forEach((element, index) => {
  189. if (element.checked === true) {
  190. count_goods_single_amount_Arr.push(goods_single_amount_Arr[index]);
  191. }
  192. });
  193. // 计算并输出显示合计
  194. document.querySelector(".total-amount").textContent =
  195. count_goods_single_amount_Arr.length > 0
  196. ? totalAmount(count_goods_single_amount_Arr)
  197. : 0;
  198. }
  199. // 加载购物车时调用自动计算
  200. window.onload = autoCount;
  201. // 商品数量变化时调用自动计算
  202. // 要先给每个商品定义onchange事件
  203. input_nums.forEach((element) => (element.onchange = autoCount));
  204. // 监听选择框状态变化事件,调用自动计算。
  205. [...document.querySelectorAll(".shopingList input[type=checkbox]")].forEach(
  206. (element) =>
  207. (element.onchange = () => {
  208. checkbox();
  209. autoCount();
  210. })
  211. );
  212. </script>
  213. </html>

3. 轮播图

  1. <!DOCTYPE html>
  2. <html lang="en">
  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. </head>
  9. <body>
  10. <style>
  11. .box {
  12. min-width: 30%;
  13. max-width: 60%;
  14. margin: 30px auto;
  15. padding: 0 10px;
  16. }
  17. .box .imgs {
  18. /* height: 30%; */
  19. }
  20. .box .imgs img {
  21. height: 100%;
  22. width: 100%;
  23. border-radius: 10px;
  24. display: none;
  25. }
  26. .box .imgs img.active {
  27. display: block;
  28. }
  29. .box .btns {
  30. display: flex;
  31. place-content: center;
  32. }
  33. .box .btns span {
  34. width: 8px;
  35. height: 8px;
  36. background-color: rgba(255, 255, 255, 0.5);
  37. border-radius: 50%;
  38. margin: -12px 3px 5px;
  39. }
  40. .box .btns span.active {
  41. background-color: rgb(1, 37, 90);
  42. }
  43. </style>
  44. <div class="box">
  45. <div class="imgs">
  46. <a href="">
  47. <img
  48. src="https://img.alicdn.com/imgextra/i3/6000000002700/O1CN01IHv4w11Voe78qwWjW_!!6000000002700-0-octopus.jpg"
  49. data-index="1"
  50. class="active"
  51. />
  52. </a>
  53. <a href="">
  54. <img
  55. src="https://gtms03.alicdn.com/tps/i3/TB1gXd1JXXXXXapXpXXvKyzTVXX-520-280.jpg"
  56. data-index="2"
  57. />
  58. </a>
  59. <a href="">
  60. <img
  61. src="https://gtms01.alicdn.com/tps/i1/TB1r4h8JXXXXXXoXXXXvKyzTVXX-520-280.jpg"
  62. data-index="3"
  63. />
  64. </a>
  65. <a href="">
  66. <img
  67. src="https://gtms02.alicdn.com/tps/i2/TB10vPXKpXXXXacXXXXvKyzTVXX-520-280.jpg"
  68. data-index="4"
  69. />
  70. </a>
  71. <a href="">
  72. <img
  73. src="https://img.alicdn.com/imgextra/i4/6000000001102/O1CN01HJ1Qxo1K0lCQcyutq_!!6000000001102-0-octopus.jpg"
  74. data-index="5"
  75. />
  76. </a>
  77. </div>
  78. <div class="btns">
  79. <span data-index="1" class="active"></span>
  80. <span data-index="2"></span>
  81. <span data-index="3"></span>
  82. <span data-index="4"></span>
  83. <span data-index="5"></span>
  84. </div>
  85. </div>
  86. <script>
  87. // 一、点击按钮变换图片
  88. // 1. 获取所有图片和按钮元素
  89. const imgs = document.querySelectorAll(".box .imgs img");
  90. const btns = document.querySelectorAll(".box .btns span");
  91. // 给所有按钮添加事件
  92. btns.forEach((btn) => (btn.onclick = setActive));
  93. // 2. 定义按钮事件函数
  94. function setActive() {
  95. // 清空所有图片和按钮的激活样式
  96. imgs.forEach((img) => img.classList.remove("active"));
  97. btns.forEach((btn) => btn.classList.remove("active"));
  98. // 根据点击按钮的索引属性确定显示的图片
  99. // 先设置点击按钮为激活状态
  100. event.target.classList.add("active");
  101. // 查找相应索引图片,并显示
  102. imgs.forEach((img) => {
  103. if (img.dataset.index === event.target.dataset.index) {
  104. img.classList.add("active");
  105. }
  106. });
  107. }
  108. // 二、定时播放
  109. // 设置定时器,模拟定时点击按钮
  110. // setInterval:三个参数,回调函数;定时时间;传给回调函数的参数
  111. // 用定时器第三个参数给回调函数传按钮数组的索引,用object.keys方法可取数组的索引为数组
  112. setInterval(
  113. (btnArr) => {
  114. // 原理:给回调函数传递按钮数组的索引,根据索引模拟点击对应的按钮
  115. // 用数组方法shift拿出第1个值,数组中就没有了该值
  116. let index = btnArr.shift();
  117. // 根据索引模拟点击,用事件派发dispatchEvent
  118. btns[index].dispatchEvent(new Event("click"));
  119. // 把当前索引放到数组后面
  120. btnArr.push(index);
  121. },
  122. 2000,
  123. Object.keys(btns)
  124. );
  125. </script>
  126. </body>
  127. </html>

4. 懒加载

  1. <!DOCTYPE html>
  2. <html lang="en">
  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. <style>
  9. h1 {
  10. font-size: 5em;
  11. }
  12. img {
  13. width: 100%;
  14. }
  15. </style>
  16. </head>
  17. <body>
  18. <h1>第1张图片</h1>
  19. <img
  20. data-src="https://img.alicdn.com/imgextra/i3/6000000002700/O1CN01IHv4w11Voe78qwWjW_!!6000000002700-0-octopus.jpg"
  21. />
  22. <h1>第2张图片</h1>
  23. <img
  24. data-src="https://gtms03.alicdn.com/tps/i3/TB1gXd1JXXXXXapXpXXvKyzTVXX-520-280.jpg"
  25. />
  26. <h1>第3张图片</h1>
  27. <img
  28. data-src="https://gtms01.alicdn.com/tps/i1/TB1r4h8JXXXXXXoXXXXvKyzTVXX-520-280.jpg"
  29. />
  30. <h1>第4张图片</h1>
  31. <img
  32. data-src="https://gtms02.alicdn.com/tps/i2/TB10vPXKpXXXXacXXXXvKyzTVXX-520-280.jpg"
  33. />
  34. <h1>第5张图片</h1>
  35. <img
  36. data-src="https://img.alicdn.com/imgextra/i4/6000000001102/O1CN01HJ1Qxo1K0lCQcyutq_!!6000000001102-0-octopus.jpg"
  37. />
  38. </body>
  39. <script>
  40. // 图片位置在视口中时才加载显示
  41. // 原理:
  42. // 把图片链接放在自定义属性data-src中
  43. // 用getBoundingClientRect()方法返回元素的位置和大小
  44. // 判断图片顶部位置是否小于视口高度window.innerHeight,小则将src属性设为data-src值
  45. // 定义加载函数
  46. function load() {
  47. // 取得所有图片转换为元素数组,遍历并判断位置,可用document.images对象
  48. [...document.images].forEach((img) => {
  49. if (img.getBoundingClientRect().top < window.innerHeight) {
  50. img.src = img.dataset.src;
  51. }
  52. });
  53. }
  54. // 定义页面加载事件
  55. window.onload = load;
  56. // 定义窗口滚动事件
  57. window.onscroll = load;
  58. </script>
  59. </html>
相关推荐
阅读 +