Blogger Information
Blog 32
fans 0
comment 0
visits 22259
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
js 急速入门之六(classList,dataset对象,选项卡,一键换肤,图片懒加载,简易轮播图)
培(信仰)
Original
905 people have browsed it

js 急速入门之六(classList,dataset对象,选项卡,一键换肤,图片懒加载,简易轮播图)

classList:设置元素的类样式

  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>classList</title>
  7. <style>
  8. .red {
  9. color:red;
  10. }
  11. .bg {
  12. background-color: yellow;
  13. }
  14. .green{
  15. color:green;
  16. }
  17. </style>
  18. </head>
  19. <body>
  20. <!-- <p class="red bg">欢迎</p> -->
  21. <p>欢迎</p>
  22. <script>
  23. const p =document.querySelector("p");
  24. // p.className='red';
  25. // p.className='red bg';
  26. // classList:用来动态的设置元素的类样式
  27. //对象有属性和方法
  28. // p.classList.add("red");
  29. // p.classList.add("bg")
  30. // p.classList.remove("bg");
  31. // p.classList.add("green","bg");
  32. // p.classList.replace("green","red");
  33. //toggle()动态切换:如果样式表有red 就移除,没有就添加
  34. p.classList.toggle("red");
  35. </script>
  36. </body>
  37. </html>

dataset对象:自定义属性

  1. <!-- id:预定义属性 -->
  2. <!-- email:自定义属性 -->
  3. <p id='aaa' data-email='a@php.cn' data-my-age='40' data-index="1">我的资料</p>
  4. <script>
  5. const p = document.querySelector("p");
  6. //使用getAttribute()方法获取自定义属性
  7. // const email = p.getAttribute("email");
  8. // console.log(email);
  9. // dataset:读写自定义属性,但是这个属性在HTML中必须使用 'data-' 为前缀
  10. // js代码中data- 前缀必须省;之后还有连接线时,连接线必须省去,原连接线后的首字母必须大写
  11. console.log(p.dataset.email);
  12. console.log(p.dataset.myAge);
  13. console.log(p.dataset.index);
  14. </script>

案例

选项卡

知识点:
数组的遍历: forEach()
数组的筛选: filter()
classList属性:classList.remove(),classList.add()

  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. .tabs {
  29. width: 300px;
  30. height: 300px;
  31. margin: 30px;
  32. background-color: #e6e6e6;
  33. display: flex;
  34. flex-direction: column;
  35. }
  36. .tab {
  37. height: 36px;
  38. display: flex;
  39. }
  40. .tab li {
  41. flex: auto;
  42. text-align: center;
  43. line-height: 36px;
  44. background-color: #fff;
  45. }
  46. .tab li.active {
  47. background-color: #e6e6e6;
  48. }
  49. .tab li:hover {
  50. cursor: pointer;
  51. }
  52. .item{
  53. padding: 20px;
  54. display: none;
  55. }
  56. .item.active {
  57. display: block;
  58. }
  59. </style>
  60. </head>
  61. <body>
  62. <div class="tabs">
  63. <!-- 导航 -->
  64. <ul class="tab">
  65. <li class="active" data-index="1">省内</li>
  66. <li data-index="2">国内</li>
  67. <li data-index="3">国际</li>
  68. </ul>
  69. <!-- details -->
  70. <ul data-index="1" class="item active" >
  71. <li><a href="">省内新闻</a></li>
  72. <li><a href="">省内新闻省内新闻</a></li>
  73. <li><a href="">省内新闻省内新闻省内新闻</a></li>
  74. </ul>
  75. <ul data-index="2" class="item">
  76. <li><a href="">国内国内国内国内</a></li>
  77. <li><a href="">国内国内国内国内国内</a></li>
  78. <li><a href="">国内国内国内国内</a></li>
  79. </ul>
  80. <ul data-index="3" class="item">
  81. <li><a href="">国际国际国际国际国际国际</a></li>
  82. <li><a href="">国际国际国际国际国际</a></li>
  83. <li><a href="">国际国际国际国际</a></li>
  84. </ul>
  85. </div>
  86. <script>
  87. const tab = document.querySelector(".tab");
  88. const items = document.querySelectorAll(".item");
  89. //1. 清空之前所有出于激活状态的选项卡,并将当前点击对象激活
  90. tab.onclick = (ev) => {
  91. // 事件绑定对象
  92. // console.log(ev.currentTarget);
  93. //事件触发对象
  94. // console.log(ev.target);
  95. [...tab.children].forEach((item) => item.classList.remove("active"));
  96. ev.target.classList.add("active");
  97. //2. 根据自定义属性data-index找到对应的列表并显示
  98. //NodeList对象内置了forEach接口
  99. items.forEach(item => item.classList.remove("active"));
  100. console.log(ev.target);
  101. [...items].filter(item => item.dataset.index === ev.target.dataset.index)[0].classList.add("active");
  102. };
  103. </script>
  104. </body>
  105. </html>

一键换肤

知识点:
动态修改 body.style.backgroundImage

  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. .container {
  9. width: 300px;
  10. display: grid;
  11. grid-template-columns: repeat(3,1fr);
  12. column-gap:10px;
  13. }
  14. .container>img{
  15. width: 100%;
  16. border:3px solid #fff;
  17. opacity: 0.6;
  18. }
  19. .container > img:active {
  20. opacity: 1;
  21. }
  22. .container > img:hover {
  23. opacity: 1;
  24. cursor:pointer;
  25. width: 105%;
  26. }
  27. body {
  28. background-image: url("static/images/1.jpg");
  29. background-repeat: no-repeat;
  30. background-size: cover;
  31. }
  32. </style>
  33. </head>
  34. <body>
  35. <div class="container">
  36. <img src="static/images/1.jpg" alt="" />
  37. <img src="static/images/2.jpg" alt="" />
  38. <img src="static/images/3.jpg" alt="" />
  39. </div>
  40. <script>
  41. //事件代理,不需要给每个图片的缩略图添加点击事件,只需要给父元素添加就可以了
  42. // document.querySelector(".container").onclick = ev=>document.body.backgroundImage = "url("+ev.target.src+")";
  43. const box = document.querySelector(".container");
  44. box.onclick = function (ev) {
  45. const body = document.body;
  46. let imgUrl = "url("+ev.target.src+")";
  47. body.style.backgroundImage = imgUrl;
  48. }
  49. </script>
  50. </body>
  51. </html>

图片懒加载

懒加载原理
先将图片的url地址存到自定义属性 data-src 中,当图片top值<视口+滚动高度时 用 data-src 替换 src
img.offsetTop < clientHeight + document.documentElement.scrollTop

知识点:setTimeout(),两个事件 scroll,load

  1. //视口高度
  2. let viewHeight = document.documentElement.clientHeight;
  3. //滚动高度
  4. document.onscroll = ev=>{
  5. console.log(document.documentElement.scrollTop);
  6. }
  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. .container {
  9. width: 500px;
  10. display: grid;
  11. gap: 10px;
  12. grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  13. }
  14. .container img {
  15. width: 100%;
  16. }
  17. </style>
  18. </head>
  19. <body>
  20. <div class="container">
  21. <img src="images/temp.jpg" alt="" data-src="images/img-1.jpg" />
  22. <img src="images/temp.jpg" alt="" data-src="images/img-2.jpg" />
  23. <img src="images/temp.jpg" alt="" data-src="images/img-3.jpg" />
  24. <img src="images/temp.jpg" alt="" data-src="images/img-4.jpg" />
  25. <img src="images/temp.jpg" alt="" data-src="images/img-5.jpg" />
  26. <img src="images/temp.jpg" alt="" data-src="images/img-6.jpg" />
  27. <img src="images/temp.jpg" alt="" data-src="images/img-7.jpg" />
  28. <img src="images/temp.jpg" alt="" data-src="images/img-8.jpg" />
  29. <img src="images/temp.jpg" alt="" data-src="images/img-9.jpg" />
  30. <img src="images/temp.jpg" alt="" data-src="images/img-10.jpg" />
  31. </div>
  32. <script>
  33. // const imgs =document.images;
  34. const images = document.querySelectorAll(".container img");
  35. const clientHeight = document.documentElement.clientHeight;
  36. window.addEventListener("scroll", layzyload);
  37. window.addEventListener("load", layzyload);
  38. function layzyload() {
  39. images.forEach((img) => {
  40. if (img.offsetTop < clientHeight + document.documentElement.scrollTop)
  41. setTimeout(() => (img.src = img.dataset.src), 500);
  42. });
  43. }
  44. // images
  45. </script>
  46. </body>
  47. </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="#"
  14. ><img src="banner/banner1.jpg" alt="" data-index="1" class="active"
  15. /></a>
  16. <a href="#"><img src="banner/banner2.jpg" alt="" data-index="2" /></a>
  17. <a href="#"><img src="banner/banner3.jpg" alt="" data-index="3" /></a>
  18. <a href="#"><img src="banner/banner4.jpg" alt="" data-index="4" /></a>
  19. </nav>
  20. <!-- 2. 图片小按钮 -->
  21. <nav class="btns">
  22. <!-- 应该根据图片的数量自动生成 -->
  23. <!-- <a href="" data-index="1" class="active"></a>
  24. <a href="" data-index="2"></a>
  25. <a href="" data-index="3"></a>
  26. <a href="" data-index="4"></a> -->
  27. </nav>
  28. <!-- 3. 翻页按钮 -->
  29. <nav class="skip">
  30. <a href="#" class="prev">&lt;</a>
  31. <a href="#" class="next">&gt;</a>
  32. </nav>
  33. </div>
  34. <script>
  35. // 所有图片
  36. const imgs = document.querySelectorAll(".container > .imgs img");
  37. //按钮组
  38. const btnGroup = document.querySelector(".container > .btns");
  39. // 翻页按钮
  40. const skip = document.querySelectorAll(".container > .skip > a");
  41. // 创建出一组与图片数量一致的小按钮
  42. function autoCreateBtns(ele, imgCount) {
  43. const frag = document.createDocumentFragment();
  44. for (let i = 0; i < imgCount; i++) {
  45. const a = document.createElement("a");
  46. a.href = "#";
  47. a.dataset.index = i + 1;
  48. if (i === 0) a.classList.add("active");
  49. frag.appendChild(a);
  50. }
  51. ele.appendChild(frag);
  52. }
  53. // 调用创建小按钮的函数
  54. autoCreateBtns(btnGroup, imgs.length);
  55. // 为刚刚生成的小按钮添加点击事件
  56. const btns = document.querySelectorAll(".container > .btns > *");
  57. // 写两个公共函数
  58. // 1. 获取激活的元素
  59. function getActiveEle(eles) {
  60. let activities = [...eles].filter((img) =>
  61. img.classList.contains("active")
  62. );
  63. return activities.shift();
  64. }
  65. // 2. 设置激活元素,根据按钮索引更新正在显示的图片
  66. function setActiveEle(btnIndex) {
  67. [imgs, btns].forEach((arr) => {
  68. // 将之前的状态重置到初始化
  69. getActiveEle(arr).classList.remove("active");
  70. arr.forEach((item) => {
  71. if (item.dataset.index === btnIndex) {
  72. item.classList.add("active");
  73. }
  74. });
  75. });
  76. }
  77. btns.forEach((btn) =>
  78. btn.addEventListener("click", (ev) =>
  79. setActiveEle(ev.target.dataset.index)
  80. )
  81. );
  82. let iMax = imgs.length;
  83. //上一张
  84. let prevSkip = document.querySelector(".prev");
  85. prevSkip.addEventListener("click", () => {
  86. let iIndex = getActiveEle(imgs).dataset.index;
  87. let iPrev = parseInt(iIndex) - 1;
  88. iPrev < 1
  89. ? setActiveEle(iMax.toString())
  90. : setActiveEle(iPrev.toString());
  91. });
  92. //下一张
  93. let nextSkip = document.querySelector(".next");
  94. nextSkip.addEventListener("click", () => {
  95. let iIndex = getActiveEle(imgs).dataset.index;
  96. let iNext = parseInt(iIndex) + 1;
  97. iNext > iMax
  98. ? setActiveEle("1")
  99. : setActiveEle(iNext.toString());
  100. });
  101. //事件派发
  102. startInterval = function () {
  103. const ev = new Event("click");
  104. nextSkip.dispatchEvent(ev);
  105. };
  106. //使用间歇式定时器
  107. let intervalID = setInterval(startInterval, 2000);
  108. let container = document.querySelector(".container");
  109. container.addEventListener("mouseover", () => clearInterval(intervalID));
  110. container.addEventListener(
  111. "mouseleave",
  112. () => (intervalID = setInterval(startInterval, 2000))
  113. );
  114. </script>
  115. </body>
  116. </html>

小结:调试过程中因为没有将事件派发封装,直接使用 setInterval() 设置派发造成一直无法达到效果。
由于没有了解setInterval用法造成时间的浪费,吃一堑长一智吧。

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