Blogger Information
Blog 57
fans 3
comment 0
visits 59796
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
JS基础-元素的增删/选项卡小实战/轮播图小实战
岂几岂几
Original
859 people have browsed it

元素的增删改

  • 创建元素

    1. 使用 document.createElement(标签名) 的方式创建元素
    1. 使用 element.innerHTML=HTML代码片段 的方式创建元素并设置为 element 的后代元素.
    • element.innerHTMLelement.innerText 的区别: 前者会把文本中的标签文本解析为 HTML 标签元素; 后者则把标签文本当作文本直接输出.
  • 插入元素

    1. 使用 element.appendChild(新元素) 的方式向父元素中插入新元素. 新元素将被插入到兄弟元素中最后的位置.
    1. 使用 element.insertBefor(新元素, 兄弟元素) 的方式在父元素中的某个子元素前插入新元素. 新元素将被插入在指定的兄弟元素之前.
  • 删除元素

  • 删除元素需要调用父元素的 removeChild(待删除子元素) 方法来执行删除.

    • 获取当前元素的父元素, 使用 element.parentNode 属性.
  • 补: 获取子节点和获取子元素的相关方法对比

    • 获取所有子节点, 用 element.childNodes 属性;
    • 获取所有子元素, 用 element.children 属性;
    • 获取子节点数量, 用 element.childNodes.length 属性;
    • 获取子元素数量, 用 element.childElementCount 属性, 或者 element.children.length 属性;
    • 获取第一个子节点, 用 element.firstChild 属性, 或者 element.childNodes[0] , 或者 element.childNodes.item(0) ;
    • 获取第一个子元素, 用 element.firstElementChild 属性, 或者 element.children[0] , 或者 element.children.item(0) ;
    • 获取最后一个子节点, 用 element.lastChild 属性, 或者 element.children[element.childNodes.length -1] , 或者 element.children.item(element.childNodes.length -1) ;
    • 获取最后一个子元素, 用 element.lastElementChild , 或者 element.children[element.childElementCount - 1] , 或者 element.children.item(element.childElementCount - 1) ;
    • 获取当前节点的前一个兄弟节点, 用 nodeElement.previousSibling 属性;
    • 获取当前元素的前一个兄弟元素, 用 eleElement.previousElementSibling 属性;
    • 获取当前节点的后一个兄弟节点, 用 nodeElement.nextSibling 属性;
    • 获取当前元素的后一个兄弟元素, 用 eleElement.nextElementSibling 属性;

选项卡实战

实现原理

  • 使用自定义属性关联选项卡标签和内容区, 即有关联的标签和内容区的 data-index 相同.
  • 非活动的标签和内容区隐藏.
  • 当动作事件(如: 点击事件/鼠标移入事件等)触发时, 执行切换选项卡高亮和内容区显示/隐藏操作.
  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 'tabs.css';
  9. </style>
  10. </head>
  11. <body>
  12. <!-- 选项卡的页签部分 -->
  13. <div class="tabs">
  14. <ul class="tab">
  15. <!-- 默认显示水果页签内容 -->
  16. <li class="active" data-index="1">水果</li>
  17. <li data-index="2">手机</li>
  18. <li data-index="3">汽车</li>
  19. </ul>
  20. <!-- 页签内容 -->
  21. <!-- 1. 水果页签内容 -->
  22. <ul class="active" data-index="1">
  23. <li>苹果</li>
  24. <li>雪梨</li>
  25. <li>香蕉</li>
  26. <li>橙子</li>
  27. </ul>
  28. <!-- 2. 手机页签内容 -->
  29. <ul data-index="2">
  30. <li>华为</li>
  31. <li>荣耀</li>
  32. <li>OPPO</li>
  33. <li>VIVO</li>
  34. </ul>
  35. <!-- 3. 汽车页签内容 -->
  36. <ul data-index="3">
  37. <li>大众</li>
  38. <li>丰田</li>
  39. <li>本田</li>
  40. <li>别克</li>
  41. </ul>
  42. </div>
  43. </body>
  44. <script>
  45. // 导航区
  46. var tab = document.querySelector('.tab');
  47. // 导航快
  48. var tabItems = document.querySelector('.tab li');
  49. // 把导航块的点击事件绑定到父元素(.tab), 利用冒泡机制触发
  50. tab.addEventListener('click', selectItem, false);
  51. // ....鼠标移入.....
  52. // tab.addEventListener('mouseover', selectItem, false);
  53. function selectItem(event) {
  54. // 导航区中非导航块的区域, 鼠标进入时, 不做处理
  55. if (event.target === event.currentTarget) {
  56. return false;
  57. }
  58. // console.log(event.target);
  59. // 获取被点击的导航块的父级元素, 再通过父级元素获取其所有的子节点(注意, 包括文本类型等HTML元素类型之外的子节点)
  60. event.target.parentNode.childNodes.forEach(function(item) {
  61. // 如果当前节点的类型是HTML元素(导航块), 则移除其active样式类
  62. if (item.nodeType === 1) {
  63. item.classList.remove('active');
  64. }
  65. });
  66. // 给当前导航块加上active样式类
  67. event.target.classList.add('active');
  68. // 获取到导航内容区的ul元素
  69. var items = document.querySelectorAll('.tabs ul:not(first-of-type)');
  70. for (var i = 0; i < items.length; i++) {
  71. // 给data-index属性值跟当前被点击的导航块的data-index值相等的导航区增加active样式类
  72. if (items[i].dataset.index == event.target.dataset.index) {
  73. items[i].classList.add('active');
  74. } else {
  75. // 不等的, 则移除active样式类.
  76. items[i].classList.remove('active');
  77. }
  78. }
  79. }
  80. </script>
  81. </html>

效果图:

轮播图实战

实现原理

  • 轮播图的图片设置为隐藏, 只显示激活状态的图片.
  • 使用自定义属性关联图片和对应的小圆点, 即关联的图片和小圆点具有相同的 data-index 属性值, 点击小圆点, 将关联的图片设置为显示.
  • 点击上一张/下一张时, 利用 element.previousElementSiblingelement.nextElementSibling 把上一张/下一张图片设置为显示, 并利用 data-index 属性把关联的小圆点设置为高亮.
  • 利用定时器, 定时执行”下一张”事件自动派发操作.
  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 'box.css';
  9. </style>
  10. </head>
  11. <body>
  12. <!-- 轮播图 -->
  13. <div class="box">
  14. <!-- 轮播图的图片区域 -->
  15. <img src="img/lb1.png" alt="" class="slider active" data-index="1" />
  16. <img src="img/lb2.png" alt="" class="slider" data-index="2" />
  17. <img src="img/lb3.png" alt="" class="slider" data-index="3" />
  18. <img src="img/lb4.png" alt="" class="slider" data-index="4" />
  19. <!-- 小黑点导航区 -->
  20. <div class="point-list">
  21. <!-- 需要用js动态生成 -->
  22. </div>
  23. <span class="skip prev">&lt;</span>
  24. <span class="skip next">&gt;</span>
  25. </div>
  26. </body>
  27. <script>
  28. var cl = console.log.bind(console);
  29. // 获取轮播图片
  30. var imgs = document.querySelectorAll("img");
  31. // 小圆点容器
  32. pointList = document.querySelector(".point-list");
  33. cl(pointList);
  34. // 根据图片的信息动态生成对应的小圆点
  35. imgs.forEach(function(img, index) {
  36. // 生成小圆点
  37. var span = document.createElement("span");
  38. // 增加样式
  39. span.classList.add("point");
  40. span.dataset.index = img.dataset.index;
  41. // 初始状态,第一个小圆点为激活状态
  42. if (index === 0) {
  43. span.classList.add("active");
  44. }
  45. // 添加到小圆点容器中
  46. pointList.appendChild(span);
  47. });
  48. // 为小黑点添加事件(以事件委托的方式,事件添加到小圆点的父节点上)
  49. pointList.addEventListener(
  50. "click",
  51. function(event) {
  52. // 出发点击事件的节点
  53. var currPoint = event.target;
  54. // 执行的事件绑定的节点
  55. var pl = event.currentTarget;
  56. // 点击非小圆点之外的小圆点容器区域, 不做处理
  57. if (pl == currPoint) return false;
  58. // 遍历图片数组
  59. imgs.forEach(function(img, i) {
  60. var imgIndex = img.dataset.index;
  61. // 显示data-index与被点击小圆点的data-index值相同的图片显示, 隐藏当前显示的图片
  62. if (currPoint.dataset.index == imgIndex) {
  63. img.classList.add("active");
  64. currPoint.classList.add("active");
  65. }
  66. // 去掉当前显示的图片以及显示为高亮的小圆点的active样式
  67. else if (img.classList.contains("active")) {
  68. img.classList.remove("active");
  69. var spot = document.querySelector(
  70. 'span[data-index="' + imgIndex + '"]'
  71. );
  72. spot.classList.remove("active");
  73. // cl(spot);
  74. }
  75. });
  76. },
  77. false
  78. );
  79. // 获取翻页按钮
  80. var skips = document.querySelectorAll(".skip");
  81. // 绑定点击事件
  82. skips.item(0).addEventListener("click", skipImg, false);
  83. skips.item(1).addEventListener("click", skipImg, false);
  84. function skipImg(event) {
  85. // 判断是上一页还是下一页
  86. var next = this.classList.contains("next") ? "+" : "-";
  87. // 获取当前显示的图片
  88. var img = document.querySelector("img.active");
  89. // 获取显示图片的data-index属性值
  90. var index = img.dataset.index;
  91. // 下一章图片的data-index属性值
  92. var nextIndex = parseInt(eval(index + next + "1"));
  93. cl(typeof nextIndex);
  94. // 边界值处理
  95. nextIndex = nextIndex > 4 ? 1 : nextIndex < 1 ? 4 : nextIndex;
  96. cl(nextIndex);
  97. // 当前显示的图片和对应小圆点取消active样式
  98. img.classList.remove("active");
  99. document.querySelector(".point.active").classList.remove("active");
  100. var nextImg = document.querySelector(
  101. 'img[data-index="' + nextIndex + '"]'
  102. );
  103. var nextPoint = document.querySelector(
  104. '.point[data-index="' + nextIndex + '"]'
  105. );
  106. nextImg.classList.add("active");
  107. nextPoint.classList.add("active");
  108. }
  109. // 轮播图容器
  110. var box = document.querySelector(".box");
  111. // 定时器
  112. var timer = null;
  113. // 2. 当鼠标移出轮播图区域时, 加回定时器, 每2秒自动切换图片
  114. box.addEventListener("mouseout", startTimer, false);
  115. // 1. 当鼠标移入轮播图区域时, 清除定时器, 由用户点击操作
  116. box.addEventListener("mouseover", clearTimer, false);
  117. // 利用定时器, 每隔一段时间执行一次事件派发, 自动触发点金"下一页"事件
  118. function startTimer() {
  119. // 创建一个点击事件
  120. var click = new Event("click");
  121. // 创建定时器, 语法: setInterver(间隔执行的回调函数, 间隔的毫秒数);
  122. timer = setInterval(function() {
  123. // 把点击事件派发给"下一页"
  124. skips.item(1).dispatchEvent(click);
  125. }, 2000);
  126. }
  127. startTimer();
  128. // 清楚定时器
  129. function clearTimer() {
  130. // 调用清除定时器的方法
  131. clearInterval(timer);
  132. }
  133. </script>
  134. </html>

运行效果图:

学习心得

  • 懒加载理解得不够到位, 选了理解得比较到位的选项卡作为作业.
  • 通过本次实战课, 自己对js的各种操作有了进一步的理解. 认识到了他们的使用场景.
  • 懒加载主要是各种偏移量, 高度等, 是相对于哪个参照物这点, 理解得不太到位. 在老师给的实例中, 给父元素绑定滚动事件, 而在事件内部, 用 event.target.scrollHeight 来获取子元素的滚动高度, 个人理解, event.target 是父元素, event.target.scrollHeight 应该是父元素的滚动条滚动的高度, 而不是子元素相对于父元素滚动的高度, 这点没绕过来. element.offsetTop 这个值, 是相对于父元素(body)的偏移量, 还是相对于文档内容区(document.documentElement)顶部的偏移量. 这点也比较模糊. 希望老师解惑.
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
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!