Blogger Information
Blog 41
fans 0
comment 0
visits 40987
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
JS原生态写法实现网页经典动画:选项卡|轮播图|懒加载
幸福敲门的博客
Original
702 people have browsed it

一、选项卡

  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. * {
  9. margin: 0;
  10. padding: 0;
  11. box-sizing: border-box;
  12. }
  13. a {
  14. text-decoration: none;
  15. color: #555;
  16. }
  17. a:hover {
  18. text-decoration: underline;
  19. color: red;
  20. }
  21. li {
  22. list-style: none;
  23. line-height: 1.6em;
  24. }
  25. li:hover {
  26. cursor: default;
  27. }
  28. .boxs {
  29. width: 300px;
  30. height: 300px;
  31. margin: 30px;
  32. background-color: #e6e6e6;
  33. display: flex;
  34. flex-direction: column;
  35. }
  36. .box {
  37. height: 36px;
  38. display: flex;
  39. }
  40. .box li {
  41. flex: auto;
  42. text-align: center;
  43. line-height: 36px;
  44. background-color: #fff;
  45. }
  46. .box li.active {
  47. background-color: #e6e6e6;
  48. }
  49. .box li:hover {
  50. cursor: pointer;
  51. }
  52. /* 默认所有选项卡只有一个显示,其它隐藏 */
  53. .lanmu{
  54. padding: 20px;
  55. display: none;
  56. overflow: hidden;
  57. text-overflow: ellipsis;
  58. white-space:nowrap;
  59. }
  60. .lanmu.active {
  61. display: block;
  62. }
  63. </style>
  64. </head>
  65. <body>
  66. <div class="boxs">
  67. <!-- 导航 -->
  68. <ul class="box">
  69. <li class="active" data-index="1">国内</li>
  70. <li data-index="2">国际</li>
  71. <li data-index="3">军事</li>
  72. <li data-index="4">财经</li>
  73. <li data-index="5">体育</li>
  74. </ul>
  75. <!-- details -->
  76. <ul data-index="1" class="lanmu active">
  77. <li><a href="">新疆铁路南通道作用显现....</a></li>
  78. <li><a href="">福建的第一次!</a></li>
  79. <li><a href="">快递从业者也能成“高级工程师”?....</a></li>
  80. <li><a href="">重庆人盼望下雪的心有多强烈?...</a></li>
  81. <li><a href="">快递从业者也能成“高级工程师”?....</a></li>
  82. <li><a href="">江苏南通:优化产业布局 护好长...</a></li>
  83. </ul>
  84. <ul data-index="2" class="lanmu">
  85. <li><a href="">外交部批驳蓬佩奥又双叒叕散布谎言....</a></li>
  86. <li><a href="">任期进入倒计时,蓬佩奥还在散播....</a></li>
  87. <li><a href="">沙漠中一处“神秘”村庄,白天出现晚上消失,当地人不..</a></li>
  88. <li><a href="">国外打出租车:上车要说“by meter”,否则可..</a></li>
  89. <li><a href="">防止特朗普启动核武器!这场谈话触及五角大.....</a></li>
  90. <li><a href="">白宫美女发言人“变脸” 网友:“化妆师集体.....</a></li>
  91. </ul>
  92. <ul data-index="3" class="lanmu">
  93. <li><a href="">俄专家呼吁复活“核幽灵”列车....</a></li>
  94. <li><a href="">印军多高官近期密集访问列城....</a></li>
  95. <li><a href="">超燃现场!多型靶弹精准打击目标</a></li>
  96. <li><a href="">穿越冰河 这些边防军人筑起钢铁....</a></li>
  97. <li><a href="">美军无人机午夜侦察南海 至上午8....</a></li>
  98. <li><a href="">中国海警舰艇编队1月13日在我钓.....</a></li>
  99. </ul>
  100. <ul data-index="4" class="lanmu">
  101. <li><a href="">别样的挂历小店</a></li>
  102. <li><a href="">丰台设50余个新冠肺炎疫苗临时接种点 已累计接...</a></li>
  103. <li><a href="">北京奇案:40幅珍贵画作在香港某画展上神秘消失</a></li>
  104. <li><a href="">美在耕耘——中国美术馆新年展”在京亮相</a></li>
  105. <li><a href="">加大备货、推惠民菜,北京商超、生鲜电商硬核保供...</a></li>
  106. <li><a href="">青岛新冠疫苗接种已达9万多人!市民将陆续免费接...</a></li>
  107. </ul>
  108. <ul data-index="5" class="lanmu">
  109. <li><a href="">山西汾酒股份胜苏州肯帝亚</a></li>
  110. <li><a href="">世界羽联更新防疫动态 内维尔等获准出战泰国赛</a></li>
  111. <li><a href="">我们始终在路上——人大网球队</a></li>
  112. <li><a href="">德国杯:勒沃库森胜法兰克福</a></li>
  113. <li><a href="">澳网资格赛现阳性病例!</a></li>
  114. <li><a href="">连救赛点!斯诺克大师赛颜丙涛6:5逆转罗伯逊进8强</a></li>
  115. </ul>
  116. </div>
  117. <script>
  118. // 事件代理
  119. const box = document.querySelector(".box");
  120. // 五个列表
  121. const lanmus = document.querySelectorAll(".lanmu");
  122. box.onclick = ev => {
  123. // 事件的绑定对象
  124. // console.log(ev.currentTarget);
  125. // 事件触发对象
  126. // console.log(ev.target);
  127. // 只需要二步:
  128. // 1. 清空之前所有处于激活状态的选项卡,并将当前点击对象激活
  129. [...box.children].forEach(lanmu => lanmu.classList.remove("active"));
  130. ev.target.classList.add("active");
  131. // 2. 根据自定义属性data-index找到对应的列表并显示出来
  132. // NodeList对象内置了forEach接口
  133. lanmus.forEach(lanmu => lanmu.classList.remove("active"));
  134. [...lanmus].filter(lanmu => lanmu.dataset.index === ev.target.dataset.index)[0].classList.add("active");
  135. };
  136. </script>
  137. </body>
  138. </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. <link rel="stylesheet" href="banner/style.css" />
  8. </head>
  9. <body>
  10. <div class="container">
  11. <!-- 1. 图片组 -->
  12. <nav class="imgs">
  13. <a href=""><img src="banner/banner1.jpg" alt="" data-index="1" class="active" /></a>
  14. <a href=""><img src="banner/banner2.jpg" alt="" data-index="2" /></a>
  15. <a href=""><img src="banner/banner3.jpg" alt="" data-index="3" /></a>
  16. <a href=""><img src="banner/banner4.jpg" alt="" data-index="4" /></a>
  17. </nav>
  18. <!-- 2. 图片小按钮 -->
  19. <nav class="btns">
  20. <!-- 这些小按钮应该根据图片数量自动生成 -->
  21. <!-- <a href="" data-index="1" class="active"></a>
  22. <a href="" data-index="2"></a>
  23. <a href="" data-index="3"></a>
  24. <a href="" data-index="4"></a> -->
  25. </nav>
  26. <!-- 3. 翻页 -->
  27. <nav class="skip">
  28. <a href="#" class="prev">&lt;</a>
  29. <a href="#" class="next">&gt;</a>
  30. </nav>
  31. </div>
  32. <script>
  33. // 所有图片
  34. const imgs = document.querySelectorAll(".container > .imgs img");
  35. // 按钮组
  36. const btnGroup = document.querySelector(".container > .btns");
  37. // 翻页按钮
  38. const skip = document.querySelector(".container > .skip");
  39. skip.addEventListener("click", skipImg, false);
  40. // 单独写一个事件监听器,为后面的事件自动派发做准备
  41. skip.children[0].addEventListener("click", skipImg, false);
  42. // 将前后翻页,使用一个回调统一处理
  43. function skipImg(ev) {
  44. // 当前激活的图片,实际上这里用不到它,而应该用它的父级<a>来判断是否存在兄弟节点
  45. let currentImg = getActiveEle(imgs);
  46. // 当前图片组父元素,注意<img>父级是<a>,<a>的父级才是需要的父节点
  47. let parentEle = currentImg.parentElement.parentElement;
  48. // 当前元素的前一个兄弟节点:previousElementSibling;
  49. let prevEle = currentImg.parentElement.previousElementSibling;
  50. // 当前元素的下一个兄弟节点:nextElementSibling;
  51. let nextEle = currentImg.parentElement.nextElementSibling;
  52. // 第一张图片, firstElementChild第一个子元素
  53. let firstImg = parentEle.firstElementChild.firstElementChild;
  54. // 最后一张图片, firstElementChild, 最后一个子元素
  55. let lastImg = parentEle.lastElementChild.firstElementChild;
  56. let activeImg = currentImg;
  57. // 向前翻页
  58. if (ev.target.classList.contains("prev")) {
  59. // 如果存在前一张图片,就使用它,否则就使用最后一张图片来更新它,形成循环显示的效果
  60. let activeImg =
  61. prevEle !== null ? prevEle.firstElementChild : lastImg;
  62. // 使用激活元素来同步更新图片与按钮
  63. setActiveEle(activeImg.dataset.index);
  64. }
  65. // 向后翻页
  66. if (ev.target.classList.contains("next")) {
  67. // 如果不存在下一张图片,就用第一张图片更新它
  68. let activeImg =
  69. nextEle !== null ? nextEle.firstElementChild : firstImg;
  70. setActiveEle(activeImg.dataset.index);
  71. }
  72. }
  73. let timer = null;
  74. const slider = document.querySelector(".container");
  75. slider.addEventListener("mouseout", startTimer, false);
  76. slider.addEventListener("mouseover", clearTimer, false);
  77. // 启动定时器
  78. function startTimer() {
  79. // 创建自定义事件对象
  80. const clickEvent = new Event("click");
  81. timer = setInterval(
  82. () => skip.children[0].dispatchEvent(clickEvent),
  83. 2000
  84. );
  85. }
  86. // 清除定时器
  87. function clearTimer() {
  88. clearInterval(timer);
  89. }
  90. // 创建出一组与图片数量对应的小按钮
  91. function autoCreateBtns(ele, imgLength) {
  92. const frag = document.createDocumentFragment();
  93. for (let i = 0; i < imgLength; i++) {
  94. const a = document.createElement("a");
  95. a.href = "#";
  96. a.dataset.index = i + 1;
  97. if (i === 0) a.classList.add("active");
  98. frag.appendChild(a);
  99. }
  100. ele.appendChild(frag);
  101. }
  102. // 调用创建小按钮的函数
  103. autoCreateBtns(btnGroup, imgs.length);
  104. // 为刚刚生成的小按钮们添加点击事件
  105. const btns = document.querySelectorAll(".container > .btns > *");
  106. // 下面声明二个公共函数
  107. // 1. 获取激活的元素
  108. function getActiveEle(eles) {
  109. let activities = [...eles].filter(img => img.classList.contains("active"));
  110. return activities.shift();
  111. }
  112. // 2. 设置激活的元素,根据按钮索引更新正在显示的图片
  113. function setActiveEle(btnIndex) {
  114. [imgs, btns].forEach(arr => {
  115. // 将之前的状态全部重置到初始化(清空)
  116. getActiveEle(arr).classList.remove("active");
  117. arr.forEach(item => {
  118. if (item.dataset.index === btnIndex) {
  119. item.classList.add("active");
  120. }
  121. });
  122. });
  123. }
  124. // 为每一个小按钮添加事件
  125. btns.forEach(btn => btn.addEventListener("click", ev => setActiveEle(ev.target.dataset.index)));
  126. </script>
  127. </body>
  128. </html>

图示:
轮播图

三、懒加载图片

  1. body>
  2. <div class="container">
  3. <img src="images/temp.jpg" alt="" data-src="images/img-1.jpg" />
  4. <img src="images/temp.jpg" alt="" data-src="images/img-2.jpg" />
  5. <img src="images/temp.jpg" alt="" data-src="images/img-3.jpg" />
  6. <img src="images/temp.jpg" alt="" data-src="images/img-4.jpg" />
  7. <img src="images/temp.jpg" alt="" data-src="images/img-5.jpg" />
  8. <img src="images/temp.jpg" alt="" data-src="images/img-6.jpg" />
  9. <img src="images/temp.jpg" alt="" data-src="images/img-7.jpg" />
  10. <img src="images/temp.jpg" alt="" data-src="images/img-8.jpg" />
  11. <img src="images/temp.jpg" alt="" data-src="images/img-9.jpg" />
  12. <img src="images/temp.jpg" alt="" data-src="images/img-10.jpg" />
  13. <img src="images/temp.jpg" alt="" data-src="images/img-11.jpg" />
  14. <img src="images/temp.jpg" alt="" data-src="images/img-12.jpg" />
  15. <img src="images/temp.jpg" alt="" data-src="images/img-13.jpg" />
  16. <img src="images/temp.jpg" alt="" data-src="images/img-14.jpg" />
  17. <img src="images/temp.jpg" alt="" data-src="images/img-15.jpg" />
  18. <img src="images/temp.jpg" alt="" data-src="images/img-16.jpg" />
  19. <img src="images/temp.jpg" alt="" data-src="images/img-17.jpg" />
  20. <img src="images/temp.jpg" alt="" data-src="images/img-18.jpg" />
  21. <img src="images/temp.jpg" alt="" data-src="images/img-19.jpg" />
  22. <img src="images/temp.jpg" alt="" data-src="images/img-20.jpg" />
  23. <img src="images/temp.jpg" alt="" data-src="images/img-21.jpg" />
  24. <img src="images/temp.jpg" alt="" data-src="images/img-22.jpg" />
  25. <img src="images/temp.jpg" alt="" data-src="images/img-23.jpg" />
  26. <img src="images/temp.jpg" alt="" data-src="images/img-24.jpg" />
  27. <img src="images/temp.jpg" alt="" data-src="images/img-25.jpg" />
  28. <img src="images/temp.jpg" alt="" data-src="images/img-26.jpg" />
  29. <img src="images/temp.jpg" alt="" data-src="images/img-27.jpg" />
  30. <img src="images/temp.jpg" alt="" data-src="images/img-28.jpg" />
  31. <img src="images/temp.jpg" alt="" data-src="images/img-29.jpg" />
  32. <img src="images/temp.jpg" alt="" data-src="images/img-30.jpg" />
  33. <img src="images/temp.jpg" alt="" data-src="images/img-31.jpg" />
  34. <img src="images/temp.jpg" alt="" data-src="images/img-32.jpg" />
  35. <img src="images/temp.jpg" alt="" data-src="images/img-33.jpg" />
  36. <img src="images/temp.jpg" alt="" data-src="images/img-34.jpg" />
  37. <img src="images/temp.jpg" alt="" data-src="images/img-35.jpg" />
  38. <img src="images/temp.jpg" alt="" data-src="images/img-36.jpg" />
  39. <img src="images/temp.jpg" alt="" data-src="images/img-37.jpg" />
  40. <img src="images/temp.jpg" alt="" data-src="images/img-38.jpg" />
  41. <img src="images/temp.jpg" alt="" data-src="images/img-39.jpg" />
  42. <img src="images/temp.jpg" alt="" data-src="images/img-40.jpg" />
  43. <img src="images/temp.jpg" alt="" data-src="images/img-41.jpg" />
  44. <img src="images/temp.jpg" alt="" data-src="images/img-42.jpg" />
  45. <img src="images/temp.jpg" alt="" data-src="images/img-43.jpg" />
  46. <img src="images/temp.jpg" alt="" data-src="images/img-44.jpg" />
  47. <img src="images/temp.jpg" alt="" data-src="images/img-45.jpg" />
  48. <img src="images/temp.jpg" alt="" data-src="images/img-46.jpg" />
  49. <img src="images/temp.jpg" alt="" data-src="images/img-47.jpg" />
  50. <img src="images/temp.jpg" alt="" data-src="images/img-48.jpg" />
  51. <img src="images/temp.jpg" alt="" data-src="images/img-49.jpg" />
  52. <img src="images/temp.jpg" alt="" data-src="images/img-50.jpg" />
  53. <img src="images/temp.jpg" alt="" data-src="images/img-51.jpg" />
  54. <img src="images/temp.jpg" alt="" data-src="images/img-52.jpg" />
  55. <img src="images/temp.jpg" alt="" data-src="images/img-53.jpg" />
  56. <img src="images/temp.jpg" alt="" data-src="images/img-54.jpg" />
  57. <img src="images/temp.jpg" alt="" data-src="images/img-55.jpg" />
  58. <img src="images/temp.jpg" alt="" data-src="images/img-56.jpg" />
  59. <img src="images/temp.jpg" alt="" data-src="images/img-57.jpg" />
  60. <img src="images/temp.jpg" alt="" data-src="images/img-58.jpg" />
  61. <img src="images/temp.jpg" alt="" data-src="images/img-59.jpg" />
  62. <img src="images/temp.jpg" alt="" data-src="images/img-60.jpg" />
  63. <img src="images/temp.jpg" alt="" data-src="images/img-61.jpg" />
  64. <img src="images/temp.jpg" alt="" data-src="images/img-62.jpg" />
  65. <img src="images/temp.jpg" alt="" data-src="images/img-63.jpg" />
  66. <img src="images/temp.jpg" alt="" data-src="images/img-64.jpg" />
  67. <img src="images/temp.jpg" alt="" data-src="images/img-65.jpg" />
  68. <img src="images/temp.jpg" alt="" data-src="images/img-66.jpg" />
  69. <img src="images/temp.jpg" alt="" data-src="images/img-67.jpg" />
  70. <img src="images/temp.jpg" alt="" data-src="images/img-68.jpg" />
  71. <img src="images/temp.jpg" alt="" data-src="images/img-69.jpg" />
  72. <img src="images/temp.jpg" alt="" data-src="images/img-70.jpg" />
  73. </div>
  74. </body>
  75. <script>
  76. const imgs = document.querySelectorAll(".container img");
  77. const clientHeight = document.documentElement.clientHeight;
  78. window.addEventListener("scroll", layzyload);
  79. // load:页面加载完成自动执行
  80. window.addEventListener("load", layzyload);
  81. function layzyload() {
  82. // 滚动高度
  83. let scrollTop = document.documentElement.scrollTop;
  84. // 遍历图片并判断是否进入到了可视区
  85. imgs.forEach(img => {
  86. // 只要当前图片距离文档顶部的偏移量,小于可视区高度与滚动高度之间则表示进入到可视区,应该显示出来
  87. // clientHeight是可视区高度,这是一个固定的值,滚动高度是动态的
  88. if (img.offsetTop < clientHeight + scrollTop) {
  89. setTimeout(() => (img.src = img.dataset.src), 500);
  90. }
  91. });
  92. }
  93. </script>

图示:
懒加载

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:
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