博客列表 >JavaScript 评论,延时加载图片,轮播图,选项卡

JavaScript 评论,延时加载图片,轮播图,选项卡

王娇
王娇原创
2020年05月28日 18:08:29558浏览

学习总结

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

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页面效果

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