博客列表 >front 21 实战:tabs-懒加载-轮播图 (0817mon)

front 21 实战:tabs-懒加载-轮播图 (0817mon)

老黑
老黑原创
2020年08月22日 20:47:23696浏览

主要内容:

  1. tabs
  2. 懒加载
  3. 轮播图
  4. 几个要点:
    • index的绑定
    • class的妙用 - 通过add、remove元素的class的名称来获得高亮等属性
    • 懒加载中的具体位置计算

1. tabs

  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>经典选项卡案例</title>
  7. <style>
  8. @import url(static/css/tabs.css);
  9. </style>
  10. </head>
  11. <body>
  12. <!-- 导航区 -->
  13. <div class="tabs">
  14. <ul class="tab">
  15. <li class="active" data-index="1">水果</li>
  16. <li data-index="2">手机</li>
  17. <li data-index="3">汽车</li>
  18. </ul>
  19. <!-- 水果对应的详情区 -->
  20. <ul class="item active" data-index="1">
  21. <li><a href="">西瓜</a></li>
  22. <li><a href="">苹果</a></li>
  23. <li><a href="">橙子</a></li>
  24. </ul>
  25. <!-- 手机对应的详情区 -->
  26. <ul class="item" data-index="2">
  27. <li><a href="">华为</a></li>
  28. <li><a href="">小米</a></li>
  29. <li><a href="">OPPO</a></li>
  30. </ul>
  31. <!-- 汽车对应的详情区 -->
  32. <ul class="item" data-index="3">
  33. <li><a href="">奇瑞</a></li>
  34. <li><a href="">吉利</a></li>
  35. <li><a href="">江淮</a></li>
  36. </ul>
  37. </div>
  38. <script src="static/js/tabs.js"></script>
  39. </body>
  40. </html>
  • css文件
  1. * {
  2. margin: 0;
  3. padding: 0;
  4. }
  5. a {
  6. text-decoration: none;
  7. color: #555;
  8. }
  9. a:hover {
  10. text-decoration: underline;
  11. color: red;
  12. }
  13. li {
  14. list-style: none;
  15. }
  16. li:hover {
  17. cursor: default;
  18. }
  19. .tabs {
  20. width: 300px;
  21. height: 300px;
  22. margin: 30px;
  23. background-color: #ddd;
  24. display: flex;
  25. flex-direction: column;
  26. }
  27. .tab {
  28. height: 36px;
  29. display: flex;
  30. }
  31. .tab li {
  32. flex: auto;
  33. text-align: center;
  34. line-height: 36px;
  35. background-color: #fff;
  36. }
  37. .tab li.active {
  38. background-color: #ddd;
  39. }
  40. /* 默认所有选项卡只有一个显示,其它隐藏 */
  41. .item {
  42. padding: 20px;
  43. display: none;
  44. }
  45. .item.active {
  46. display: block;
  47. }
  • js部分
  1. // 1. 获取导航
  2. var tab = document.querySelector(".tab");
  3. // console.log(tab);
  4. // 2. 获取详情页
  5. var items = document.querySelectorAll(".item");
  6. // console.log(items);
  7. // 3. 给导航添加点击事件(事件代理/事件委托/冒泡)
  8. tab.addEventListener("click", show, false);
  9. tab.addEventListener("mouseover", show, false);
  10. // 4. 声明show()函数
  11. function show(ev) {
  12. // ev: 事件对象
  13. // ev.type: 事件类型,如click,mouseover,input....
  14. // console.log(ev.type);
  15. // ev.target: 事件的触发者
  16. // console.log(ev.target);
  17. // ev.currentTarget: 事件绑定者
  18. // console.log(ev.currentTarget);
  19. // 4-1. 清除除当前高亮选项卡之外的选项卡的高亮样式
  20. // console.log(ev.currentTarget.children);
  21. ev.currentTarget.childNodes.forEach(function (item) {
  22. if (item.nodeType === 1) item.classList.remove("active");
  23. }); // 1标示是非text的元素,也就是正常的元素
  24. // 4-2. 应该将用户点击的当前选项卡高亮显示
  25. ev.target.classList.add("active");
  26. // 4-3. 清空原有列表
  27. items.forEach(function (item) {
  28. item.classList.remove("active");
  29. });
  30. // 4-4. 将选项卡对应的内容进行切换(根据导航和详情中的data-index)
  31. items.forEach(function (item) {
  32. // console.log(item);
  33. // console.log(ev.target.dataset.index, item.dataset.index);
  34. if (ev.target.dataset.index === item.dataset.index) {
  35. item.classList.add("active");
  36. }
  37. });
  38. }

2. 懒加载

  • 基本原理
  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>懒加载的原理</title>
  7. <link rel="stylesheet" href="static/css/lazy-base.css" />
  8. </head>
  9. <body>
  10. <div class="parent">
  11. <div class="child"></div>
  12. </div>
  13. <script>
  14. var parent = document.querySelector(".parent");
  15. var child = document.querySelector(".child");
  16. // 1. 这四个属性的值,与css样式相关
  17. console.log("元素的高度: ", child.offsetHeight);
  18. console.log("元素的宽度: ", child.offsetWidth);
  19. console.log("距离父元素的左偏移量: ", child.offsetLeft);
  20. console.log("距离父元素的顶部偏移量: ", child.offsetTop);
  21. // 2. 元素内容区大小
  22. // content + padding
  23. console.log(child.clientHeight);
  24. console.log(child.clientWidth);
  25. console.log(document.documentElement.clientHeight);
  26. </script>
  27. </body>
  28. </html>

图示如下:

  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>懒加载实现</title>
  7. </head>
  8. <body>
  9. <div class="container">
  10. <img src="images/temp.jpg" alt="" data-src="images/img-1.jpg" />
  11. <img src="images/temp.jpg" alt="" data-src="images/img-2.jpg" />
  12. <img src="images/temp.jpg" alt="" data-src="images/img-3.jpg" />
  13. <img src="images/temp.jpg" alt="" data-src="images/img-4.jpg" />
  14. <img src="images/temp.jpg" alt="" data-src="images/img-5.jpg" />
  15. <img src="images/temp.jpg" alt="" data-src="images/img-6.jpg" />
  16. <img src="images/temp.jpg" alt="" data-src="images/img-7.jpg" />
  17. <img src="images/temp.jpg" alt="" data-src="images/img-8.jpg" />
  18. <img src="images/temp.jpg" alt="" data-src="images/img-70.jpg" />
  19. </div>
  20. <script>
  21. // 1. 获取所有的图片
  22. // 用css选择器选择图片,class前面需要有.,但如果是tab则不需要。
  23. var imgs = document.querySelectorAll(".container img");
  24. // 2. 获取文档的高度
  25. var clientHeight = document.documentElement.clientHeight;
  26. // 3. 监听滚动事件
  27. window.addEventListener("scroll", function () {
  28. lazyload(imgs, clientHeight);
  29. },
  30. false
  31. );
  32. // 4. 懒加载函数
  33. function lazyload(imgs, clientHeight) {
  34. // 获取文档的滚动大小
  35. var scrollTop = document.documentElement.scrollTop;
  36. // 遍历图片,判断是否进入到可视区
  37. // 下面这个公式很重要,clientHeight指的就是浏览器的可视区高度
  38. // scrollTop则是页面卷上去的高度吧
  39. imgs.forEach(function (img) {
  40. if (img.offsetTop <= clientHeight + scrollTop) {
  41. img.src = img.dataset.src;
  42. }
  43. });
  44. }
  45. </script>
  46. </body>
  47. </html>
  1. .parent {
  2. height: 400px;
  3. width: 300px;
  4. padding: 5px;
  5. background-color: lightblue;
  6. border: 5px solid;
  7. overflow: scroll;
  8. position: relative;
  9. }
  10. .parent .child {
  11. height: 500px;
  12. width: 400px;
  13. padding: 5px;
  14. background-color: lightgreen;
  15. background-clip: content-box;
  16. border: 5px solid;
  17. position: relative;
  18. left: 10px;
  19. top: 20px;
  20. }

3. 轮播

  • 轮播的要点:
    • a-下面的小圆点及高亮;
    • b-左右的切换;
    • c-active被通过class名称的方式来改变属性
  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>轮播图</title>
  7. <link rel="stylesheet" href="static/css/slider.css" />
  8. </head>
  9. <body>
  10. <div class="box">
  11. <img src="banner/banner1.jpg" alt="" data-index="1" class="slider active"/>
  12. <img src="banner/banner2.jpg" alt="" data-index="2" class="slider" />
  13. <img src="banner/banner3.jpg" alt="" data-index="3" class="slider" />
  14. <img src="banner/banner4.jpg" alt="" data-index="4" class="slider" />
  15. <div class="point-list">
  16. <!-- 下面这段小圆点是通过js动态生成的,因为要跟具体图片的数量报纸一致,
  17. 并且index要跟图片对应起来 -->
  18. <!-- <span class="point active" data-index="1"></span>
  19. <span class="point" data-index="2"></span>
  20. <span class="point" data-index="3"></span> -->
  21. </div>
  22. <span class="skip prev">&lt;</span>
  23. <span class="skip next">&gt;</span>
  24. </div>
  25. <script src="static/js/slider.js"></script>
  26. </body>
  27. </html>
  1. ul,
  2. li {
  3. margin: 0;
  4. padding: 0;
  5. list-style: none;
  6. }
  7. .box {
  8. /*定位父级*/
  9. position: relative;
  10. width: 1000px;
  11. height: 350px;
  12. margin: 0 auto;
  13. }
  14. .box .slider {
  15. width: 1000px;
  16. height: 350px;
  17. display: none;
  18. }
  19. .box .slider.active {
  20. display: block;
  21. }
  22. .box .point-list {
  23. position: absolute;
  24. /*绝对定位的环境下的水平居中方式*/
  25. left: 50%;
  26. margin-left: -38px;
  27. top: 310px;
  28. }
  29. .box .point-list .point {
  30. display: inline-block;
  31. width: 12px;
  32. height: 12px;
  33. margin: 0 5px;
  34. background-color: white;
  35. border-radius: 100%;
  36. }
  37. .box .point-list .point.active {
  38. background-color: black;
  39. }
  40. .box .point-list .point:hover {
  41. cursor: pointer;
  42. }
  43. .skip {
  44. position: absolute;
  45. top: 140px;
  46. display: inline-block;
  47. width: 40px;
  48. height: 80px;
  49. text-align: center;
  50. line-height: 80px;
  51. background-color: lightgray;
  52. color: white;
  53. opacity: 0.2;
  54. font-size: 36px;
  55. }
  56. .box .prev {
  57. left: 0;
  58. }
  59. .box .next {
  60. right: 0;
  61. }
  62. .box .skip:hover {
  63. cursor: pointer;
  64. opacity: 0.5;
  65. color: black;
  66. }
  1. // 获取轮播图片
  2. var imgs = document.querySelectorAll("img");
  3. // 获取小圆点组
  4. var pointList = document.querySelector(".point-list");
  5. // 动态生成小圆点
  6. imgs.forEach(function(img, index) {
  7. var span = document.createElement("span");
  8. if (index == 0) span.classList.add("point", "active");
  9. span.classList.add("point");
  10. // 给当前的小圆点添加自定义的data-index
  11. span.dataset.index = img.dataset.index;
  12. pointList.appendChild(span);
  13. });
  14. // 获取到所有的小圆点
  15. var points = document.querySelectorAll(".point");
  16. // 给小圆点添加事件(代理)
  17. pointList.addEventListener("click", function (ev) {
  18. imgs.forEach(function (img) {
  19. if (img.dataset.index === ev.target.dataset.index) {
  20. imgs.forEach(function (img) {
  21. img.classList.remove("active"); // 先将其他的高亮取消掉。
  22. });
  23. img.classList.add("active");
  24. // 设置与当前图片对应的小圆点高亮显示
  25. // 因为这个功能要多处使用,这里将它声明为公共函数
  26. setPointActive(img.dataset.index);
  27. }
  28. });
  29. });
  30. // 设置与当前图片对应的小圆点高亮显示;
  31. function setPointActive(imgIndex) {
  32. points.forEach(function (point) {
  33. point.classList.remove("active");
  34. });
  35. points.forEach(function (point) {
  36. if (point.dataset.index === imgIndex) point.classList.add("active");
  37. });
  38. }
  39. // ----------------- 翻页功能 -----------------
  40. // 获取翻页按钮
  41. var skip = document.querySelectorAll(".skip");
  42. // 添加事件
  43. skip.item(0).addEventListener("click", skipImg, false);
  44. skip.item(1).addEventListener("click", skipImg, false);
  45. // 翻页显示图片的回调方法
  46. function skipImg(ev) {
  47. // 1. 获取当前的图片
  48. var currentImg = null;
  49. imgs.forEach(function (img) {
  50. if (img.classList.contains("active")) {
  51. currentImg = img; // 选择目前激活的图片并显示
  52. }
  53. });
  54. // console.log(currentImg);
  55. // 2. 判断是否是点击了显示前一张的按钮?
  56. if (ev.target.classList.contains("prev")) {
  57. // 为了显示出来前一张,必须将当前图片的激活去掉
  58. currentImg.classList.remove("active");
  59. // 将当前图片的前一张图片设置为当前图片
  60. currentImg = currentImg.previousElementSibling;
  61. // console.log(currentImg);
  62. // 如果存在前一张,再显示它,否则进入循环,显示最后一张
  63. if (currentImg !== null && currentImg.nodeName === "IMG") {
  64. currentImg.classList.add("active");
  65. } else {
  66. currentImg = imgs[imgs.length - 1];// 返回到最后一张图片
  67. currentImg.classList.add("active");
  68. }
  69. }
  70. // 3. 判断是否是点击了显示下一张的按钮?
  71. if (ev.target.classList.contains("next")) {
  72. // 为了显示出来前一张,必须将当前图片的激活去掉
  73. currentImg.classList.remove("active");
  74. // 将当前图片的前一张图片设置为当前图片
  75. currentImg = currentImg.nextElementSibling;
  76. // console.log(currentImg);
  77. // 如果存在下一张,再显示它,否则进入循环,显示第一张
  78. if (currentImg !== null && currentImg.nodeName === "IMG") {
  79. currentImg.classList.add("active");
  80. } else {
  81. currentImg = imgs[0]; // 返回到了第一张图片
  82. currentImg.classList.add("active");
  83. }
  84. }
  85. // 小圆点高亮
  86. setPointActive(currentImg.dataset.index);
  87. }

4. 作业:

  • 给轮播图添加自动播放功能,要求鼠标移入时自动停止播放并等用户操作
  • 鼠标移出时, 2秒后自动播放
    间歇式定时器
    setInterval(function(){}, 时间)
  1. // 自动轮播图
  2. let autoStart = setInterval(autoSlide, 1000);
  3. function autoSlide(){
  4. var currentImg = null;
  5. imgs.forEach(function (img) {
  6. if (img.classList.contains("active")) {
  7. currentImg = img;
  8. currentImg.classList.remove("active");
  9. }});
  10. currentImg = currentImg.nextElementSibling;
  11. if (currentImg !== null && currentImg.nodeName === "IMG") {
  12. currentImg.classList.add("active");
  13. } else {
  14. currentImg = imgs[0];
  15. currentImg.classList.add("active");
  16. }
  17. setPointActive(currentImg.dataset.index);
  18. }
  19. // imgs.addEventListener("mouseover",function(){clearInterval(autoStart);}, false);
  20. // imgs.addEventListener("mouseout", function(){autoStart = setInterval(autoSlide, 2000);}, false);
  21. // 貌似直接利用imgs不行。box才可以。
  22. box = document.querySelector(".box");
  23. box.addEventListener("mouseover", function(){clearInterval(autoStart);}, false);
  24. box.addEventListener("mouseout", function(){autoStart = setInterval(autoSlide, 1000);}, false);

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