Blogger Information
Blog 64
fans 6
comment 2
visits 82993
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
JavaScript 评论,延时加载图片,轮播图,选项卡
王娇
Original
559 people have browsed it

学习总结

  • 冒泡方法加载事件时,要注意当前是哪个元素触发的事件
  • 事件委托可以模拟用户操作,提高代码复用

1.1首页index.php

  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>javaScript 轮播图 选项卡 懒加载</title>
  7. <link rel="stylesheet" href="css/index.css">
  8. </head>
  9. <body>
  10. <div class="box">
  11. <div class="bannerBox">
  12. <img src="images/banner/banner1.jpg" alt="" data-index='1' class="slider active">
  13. <img src="images/banner/banner2.jpg" alt="" data-index='2' class="slider">
  14. <img src="images/banner/banner3.jpg" alt="" data-index='3' class="slider">
  15. <img src="images/banner/banner4.jpg" alt="" data-index='4' class="slider">
  16. <div class="pointList">
  17. <!-- 图片对应的小圆点应该按照图片的个数动态生成 -->
  18. <!-- <span class="point active"></span>
  19. <span class="point"></span>
  20. <span class="point"></span>
  21. <span class="point"></span> -->
  22. </div>
  23. <span class="skip prev">&lt;</span>
  24. <span class="skip next">&gt;</span>
  25. </div>
  26. <!-- 轮播图的js代码 -->
  27. <script src="js/banner.js"></script>
  28. <!-- 选项卡和图片延时加载 -->
  29. <div class="main">
  30. <!-- 选项卡 -->
  31. <div class="tabCard">
  32. <div class="tab">
  33. <div class="active" data-food-index="1">凉菜</div>
  34. <div data-food-index="2">热菜</div>
  35. <div data-food-index="3">甜品</div>
  36. <div data-food-index="4">酒水</div>
  37. </div>
  38. <div class="item active" data-food-index="1">
  39. <div>五香酱牛肉</div>
  40. <div>凉拌笋丝</div>
  41. <div>果仁菠菜</div>
  42. <div>大拌菜</div>
  43. </div>
  44. <div class="item" data-food-index="2">
  45. <div>宫爆鸡丁</div>
  46. <div>鱼香肉丝</div>
  47. <div>锅包肉</div>
  48. <div>木须肉</div>
  49. </div>
  50. <div class="item" data-food-index="3">
  51. <div>蛋糕</div>
  52. <div>冰淇淋</div>
  53. <div>蛋挞</div>
  54. <div>饼干</div>
  55. </div>
  56. <div class="item" data-food-index="4">
  57. <div>橙汁</div>
  58. <div>啤酒</div>
  59. <div>二锅头</div>
  60. <div>雪碧</div>
  61. </div>
  62. </div>
  63. <!-- 选项卡的js代码 -->
  64. <script src="js/tabCard.js"></script>
  65. <!-- 图片延时加载 -->
  66. <div class="imgBox" onscroll="">
  67. <?php for($i=1;$i<=70;$i++):?>
  68. <img src="images/lazoyLoad/temp.jpg" alt="" data-src="<?php echo 'images/lazoyLoad/img-'.$i.'.jpg'; ?>">
  69. <?php endfor;?>
  70. </div>
  71. <!-- 图片延时加载js代码 -->
  72. <script src="js/lazyLoad.js"></script>
  73. </div>
  74. <!-- 评论区 -->
  75. <div class="commentBox">
  76. <textarea name="" id="" cols="165" rows="10" placeholder="输入评论"></textarea>
  77. <button>发表评论</button>
  78. <div class="comm">
  79. <!-- <div class="item">
  80. <span>写的好棒</span>
  81. <button>删除</button>
  82. </div>
  83. <div class="item">
  84. <span>写的好棒</span>
  85. <button>删除</button>
  86. </div>
  87. <div class="item">
  88. <span>写的好棒</span>
  89. <button>删除</button>
  90. </div> -->
  91. </div>
  92. </div>
  93. <script src="js/comment.js"></script>
  94. </div>
  95. </body>
  96. </html>

1.2首页样式

  1. * {
  2. padding: 0px;
  3. margin: 0px;
  4. box-sizing: border-box;
  5. font-size: 12px;
  6. }
  7. .box {
  8. width: 1020px;
  9. min-height: 600px;
  10. margin-top: 5px;
  11. margin-left: auto;
  12. margin-right: auto;
  13. }
  14. /* 轮播图 */
  15. .box > .bannerBox {
  16. /* 轮播图相对定位,为了定位其中的上一张,下一张和图片圆点的位置 */
  17. position: relative;
  18. width: 100%;
  19. height: 350px;
  20. }
  21. /* 轮播图图片 */
  22. .box > .bannerBox > .slider {
  23. width: 100%;
  24. height: 350px;
  25. display: none;
  26. }
  27. .box > .bannerBox > .slider.active {
  28. display: block;
  29. }
  30. /* 轮播图上图片对应的圆点 */
  31. .box > .bannerBox > .pointList {
  32. position: absolute;
  33. left: 50%;
  34. top: 330px;
  35. }
  36. .box > .bannerBox > .pointList .point {
  37. display: inline-block;
  38. width: 12px;
  39. height: 12px;
  40. border-radius: 100%;
  41. margin: 0px 5px;
  42. background-color: white;
  43. }
  44. .box > .bannerBox > .pointList .point.active {
  45. background-color: black;
  46. }
  47. .box > .bannerBox > .pointList .point:hover {
  48. cursor: pointer;
  49. }
  50. /* 轮播图上一张和下一张切换的按钮 */
  51. .box > .bannerBox > .skip {
  52. display: inline-block;
  53. position: absolute;
  54. background-color: #ccc;
  55. color: white;
  56. opacity: 0.2;
  57. top: 140px;
  58. width: 40px;
  59. height: 70px;
  60. line-height: 70px;
  61. text-align: center;
  62. font-size: 4rem;
  63. }
  64. .box > .bannerBox > .skip.prev {
  65. left: 0px;
  66. }
  67. .box > .bannerBox > .skip.next {
  68. right: 0px;
  69. }
  70. .box > .bannerBox > .skip:hover {
  71. cursor: pointer;
  72. opacity: 0.5;
  73. color: black;
  74. }
  75. /* 选项卡 */
  76. .tabCard {
  77. margin-top: 10px;
  78. border: 1px solid #ccc;
  79. border-radius: 5px;
  80. width: 400px;
  81. height: 300px;
  82. text-align: center;
  83. }
  84. /* 选项卡和图片懒加载 */
  85. .main {
  86. display: flex;
  87. flex-flow: row nowrap;
  88. }
  89. /* 选项卡头部 */
  90. .tabCard > .tab {
  91. display: flex;
  92. flex-flow: row nowrap;
  93. }
  94. .tabCard > .tab > div:hover {
  95. cursor: pointer;
  96. }
  97. .tabCard > .tab > div {
  98. background-color: white;
  99. border: 1px solid #ccc;
  100. border-radius: 5px;
  101. margin: 3px 3px;
  102. padding: 5px 0px;
  103. width: 95px;
  104. height: 37px;
  105. font-size: 1.5rem;
  106. font-weight: bolder;
  107. }
  108. .tabCard > .tab > div.active {
  109. background-color: #313c46;
  110. color: white;
  111. }
  112. /* 选项卡内容 */
  113. .tabCard > .item {
  114. text-align: left;
  115. display: none;
  116. }
  117. .tabCard > .item > div {
  118. margin-left: 10px;
  119. margin-top: 10px;
  120. font-size: 1.4rem;
  121. }
  122. .tabCard > .item.active {
  123. display: block;
  124. }
  125. /* 图片延时加载 */
  126. .main > .imgBox {
  127. height: 300px;
  128. /* 添加滚动条 */
  129. overflow: auto;
  130. display: grid;
  131. gap: 10px;
  132. grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  133. }
  134. .main > .imgBox > img {
  135. width: 100%;
  136. }
  137. /* 评论区 */
  138. .commentBox {
  139. min-height: 300px;
  140. margin-bottom: 20px;
  141. margin-top: 10px;
  142. }
  143. .commentBox > .comm {
  144. margin-top: 10px;
  145. display: flex;
  146. flex-flow: column nowrap;
  147. justify-content: space-evenly;
  148. align-items: center;
  149. }
  150. .commentBox > .comm > .item {
  151. width: 100%;
  152. margin: 5px 0px;
  153. height: 50px;
  154. border: 1px solid #ccc;
  155. display: flex;
  156. flex-flow: row nowrap;
  157. justify-content: space-between;
  158. align-items: center;
  159. }
  160. .commentBox > .comm > .item > button {
  161. height: 30px;
  162. width: 100px;
  163. }

2.1轮播图js代码bannre.js

  1. var imgs = document.querySelectorAll("img");
  2. var pointList = document.querySelector(".pointList");
  3. //动态给每张图片生成一个小圆点
  4. imgs.forEach(function (img, index) {
  5. var span = document.createElement("span");
  6. //默认显示的是第一张图片
  7. if (index === 0) {
  8. // classList对象是给标签添加类样式
  9. span.classList.add("point", "active");
  10. }
  11. span.classList.add("point");
  12. // dataset对象给标签添加“data-变量名”属性,访问“标签.dataset.变量名”
  13. span.dataset.index = img.dataset.index;
  14. pointList.appendChild(span);
  15. });
  16. //获取所有的小圆点
  17. var points = document.querySelectorAll(".point");
  18. // 为每一个小圆点添加click事件,使用事件冒泡,只需要给它们的父元素添加click事件即可
  19. //addEventListener添加事件监听,第一个参数是事件名称,第2个参数是回调函数,第3个参数是false是冒泡方式
  20. pointList.addEventListener(
  21. "click",
  22. function (ev) {
  23. //ev.target是当前哪个元素发生了click事件,console.log(ev.target);
  24. //ev.currentTarget当前监听的是哪个元素,是div class='pointList'
  25. currentSpan = ev.target;
  26. //判断是不是点击在小圆点之外的pointList的地方,如果点的不是小圆点,则不改变属性样式
  27. if (currentSpan !== ev.currentTarget) {
  28. imgs.forEach(function (img) {
  29. //1.每个图片的active类样式先清除
  30. img.classList.remove("active");
  31. //2.如果当前图片的data-index属性与点击的小圆点的data-index属性相同,则给图片添加active类属性
  32. if (img.dataset.index === currentSpan.dataset.index) {
  33. img.classList.add("active");
  34. setPointActive(currentSpan);
  35. }
  36. });
  37. }
  38. },
  39. false
  40. );
  41. //设置当前被点击的小圆点为高亮
  42. function setPointActive(ele) {
  43. points.forEach(function (point) {
  44. //先清除所有小圆点的高亮,也就是active属性
  45. point.classList.remove("active");
  46. //如果当前小圆点的index值===被点击的小圆点的index值,则当前小圆点设置为高亮,也就是添加active属性
  47. if (point.dataset.index === ele.dataset.index) {
  48. point.classList.add("active");
  49. }
  50. });
  51. }
  52. //获取左,右的翻页按钮
  53. var skip = document.querySelectorAll(".skip");
  54. //添加点击事件
  55. skip.item(0).addEventListener("click", skipImg, false);
  56. skip.item(1).addEventListener("click", skipImg, false);
  57. function skipImg(ev) {
  58. //获取当前显示的图片
  59. var currentImg = null;
  60. //获取当前点击的是哪个按钮,是前一页,还是下一页
  61. var currentSkip = ev.target;
  62. imgs.forEach(function (img) {
  63. //如果当前图片有类属性active,就是当前显示的图片,获取这张图片
  64. if (img.classList.contains("active")) {
  65. currentImg = img;
  66. }
  67. });
  68. //当点击前一页按钮
  69. if (currentSkip.classList.contains("prev")) {
  70. //清除当前图片的active样式
  71. currentImg.classList.remove("active");
  72. //previousElementSibling获取当前元素的上一个元素,也就是获取上张图片,然后设置active样式
  73. currentImg = currentImg.previousElementSibling;
  74. //如果上一张图片不存在,则设置当前图片为最后一张图片,形成一个循环
  75. if (currentImg !== null && currentImg.nodeName === "IMG") {
  76. currentImg.classList.add("active");
  77. } else {
  78. currentImg = imgs.item(imgs.length - 1);
  79. currentImg.classList.add("active");
  80. }
  81. setPointActive(currentImg);
  82. }
  83. //当点击下一页按钮
  84. if (currentSkip.classList.contains("next")) {
  85. //清除当前图片的active样式
  86. currentImg.classList.remove("active");
  87. //nextElementSibling获取当前元素的下一个元素,也就是获取下一张图片,然后设置active样式
  88. currentImg = currentImg.nextElementSibling;
  89. //如果下一张图片不存在,则设置当前图片为第一张图片,形成一个循环
  90. if (currentImg !== null && currentImg.nodeName === "IMG") {
  91. currentImg.classList.add("active");
  92. } else {
  93. currentImg = imgs.item(0);
  94. currentImg.classList.add("active");
  95. }
  96. setPointActive(currentImg);
  97. }
  98. }
  99. //先获取整个轮播图
  100. var bannerBox = document.querySelector(".bannerBox");
  101. //设置一个定时器
  102. var timer = null;
  103. //当鼠标移出轮播时,设置定时器,每2秒做一个事件派发,模拟点击下一页按钮
  104. bannerBox.addEventListener("mouseout", timerStart, false);
  105. //当鼠标移入轮播时,清除定时器
  106. bannerBox.addEventListener("mouseover", timerEnd, false);
  107. function timerStart() {
  108. var click = new Event("click");
  109. //setInterval设置定时器,每2秒点击一下下一页按钮
  110. timer = setInterval(function () {
  111. //给下一页按钮做一个事件派发,就是模拟点击一页按钮
  112. skip.item(1).dispatchEvent(click);
  113. }, 2000);
  114. }
  115. //clearInterval(),清除定时器
  116. function timerEnd() {
  117. clearInterval(timer);
  118. }
  119. //当页面第一次加载时,启动定时器
  120. timerStart();

2.2评论区js代码comment.js

  1. var commBtn = document.querySelector(".commentBox>button");
  2. var commText = document.querySelector(".commentBox>textarea");
  3. var comm = document.querySelector(".commentBox>.comm");
  4. commBtn.addEventListener(
  5. "click",
  6. function () {
  7. var textValue = commText.value; //评论内容
  8. var div = document.createElement("div");
  9. div.classList.add("item");
  10. var span = document.createElement("span");
  11. span.innerText = textValue;
  12. var btn = document.createElement("button");
  13. btn.innerText = "删除";
  14. btn.addEventListener(
  15. "click",
  16. function (ev) {
  17. if (confirm("是否删除该评论?")) {
  18. ev.target.parentNode.parentNode.removeChild(ev.target.parentNode);
  19. }
  20. },
  21. false
  22. );
  23. div.appendChild(span);
  24. div.appendChild(btn);
  25. if (comm.childElementCount === 0) {
  26. comm.appendChild(div);
  27. } else {
  28. comm.insertBefore(div, comm.firstElementChild);
  29. }
  30. commText.value = "";
  31. },
  32. false
  33. );

2.3延时加载js代码lazyLoad.js

  1. //获取图片容器imgbox
  2. var imgBox = document.querySelector(".imgBox");
  3. //获取所有图片
  4. var boxImages = document.querySelectorAll(".imgBox img");
  5. //图片所在的div的可视高度
  6. var clientHeight = imgBox.clientHeight;
  7. imgBox.addEventListener(
  8. "scroll",
  9. function () {
  10. lazyLoad(boxImages, clientHeight);
  11. },
  12. false
  13. );
  14. function lazyLoad(boxImages, clientHeight) {
  15. var scrollTop = imgBox.scrollTop;
  16. boxImages.forEach(function (img) {
  17. if (img.offsetTop <= clientHeight + scrollTop) img.src = img.dataset.src;
  18. });
  19. }

2.4选项卡js代码tabCard.js

  1. var tabs = document.querySelector(".tab");
  2. var items = document.querySelectorAll(".item");
  3. tabs.addEventListener("click", showItem, false);
  4. function showItem(ev) {
  5. //点击的是选项卡图标,显示切换
  6. var currentTab = ev.target;
  7. if (ev.target !== ev.currentTarget) {
  8. //遍历tabs的子结点,就是每个tab选项卡
  9. tabs.childNodes.forEach(function (tab) {
  10. //确定选择的是DIV选项卡
  11. if (tab.nodeName === "DIV") {
  12. //清除选项卡的active类样式
  13. tab.classList.remove("active");
  14. }
  15. });
  16. currentTab.classList.add("active");
  17. //遍历选项卡内容的div
  18. items.forEach(function (item) {
  19. //先清除内容上的active的类样式
  20. item.classList.remove("active");
  21. //如果当前点击的选项卡的data-food-index中的内容等于内容中的data-food-index,则内容显示
  22. if (currentTab.dataset.foodIndex === item.dataset.foodIndex) {
  23. item.classList.add("active");
  24. }
  25. });
  26. }
  27. }

3页面效果

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:为了便于记忆和理解 , 咱们的js代码都是精简且高效, 脚本并不是越多越好, 要注意效率
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post