Blogger Information
Blog 94
fans 0
comment 0
visits 92960
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
【JS】模块实战:经典选项卡=>重点,可直接应用项目
可乐随笔
Original
309 people have browsed it

模块实战:经典选项卡

总结:

1、HTML DOM结构:写栏目组和内容组
2、获取栏目组和内容组的元素
3、调用模块生成栏目组和内容组的内容
4、在父级绑定点击事件,利用事件冒泡原理调用事件委托,调用 设置当前按钮高亮模块方法和显示对应内容区的模块方法。

HTML示范:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>实战1:经典选项卡</title>
  8. <style>
  9. /* 隐藏 */
  10. .hidden {
  11. display: none;
  12. }
  13. /* 显示 */
  14. .active {
  15. display: block;
  16. }
  17. .type > *.active,
  18. .content {
  19. background-color: lightgreen;
  20. }
  21. </style>
  22. </head>
  23. <body>
  24. <div class="box">
  25. <!-- 栏目组 -->
  26. <div class="type" style="display: flex;"></div>
  27. <!-- 内容组 -->
  28. <div class="content"></div>
  29. </div>
  30. <script type="module">
  31. //导入模块
  32. import * as tabs from "./modules/tabs.js";
  33. // 1. 获取栏目,内容容器元素
  34. const type = document.querySelector('.type');
  35. const content = document.querySelector('.content');
  36. //console.log(type,content);
  37. // 2. 页面加载完成时,创建栏目栏目和对应的内容
  38. window.onload = () => {
  39. // console.log('页面加载完成')
  40. //自动生成栏目和内容数据
  41. tabs.createTab(type,content);
  42. }
  43. // 3.点击栏目时,设置按钮的状态,与按钮对应的内容的状态
  44. // 事件委托(事件冒泡)
  45. type.onclick = (ev) => {
  46. //因为存在事件委托,所以就需要区分不同的事件主体
  47. //使用ev来传递触发主体
  48. //触发主体:ev.target
  49. //绑定主体:ev.currentTarget,是触发主体的父级
  50. // 1. 当前按钮高亮
  51. tabs.setBtnStatus(ev);
  52. // 2. 与按钮对应的内容显示出来
  53. // ev.target:当前按钮
  54. tabs.setContentStatus(ev,ev.target)
  55. }
  56. </script>
  57. </body>
  58. </html>

JS示范:

  1. // todo 选项卡的数据及方法
  2. // * 栏目数据
  3. const cates = [
  4. { cid: 1, cname: '国际新闻' },
  5. { cid: 2, cname: '国内新闻' },
  6. { cid: 3, cname: '省内新闻' },
  7. ];
  8. // * 列表数据
  9. // 列表数据,必须与指定栏目,一一对应
  10. const details = [
  11. {
  12. key: 1,
  13. cid: 1,
  14. content: [
  15. {
  16. title: '江泽民伟大光辉的一生',
  17. url: 'https://news.ifeng.com/c/8LPwtTX7hsA'
  18. },
  19. {
  20. title: '江泽民伟大光辉的一生',
  21. url: 'https://news.ifeng.com/c/8LPwtTX7hsA'
  22. },
  23. {
  24. title: '江泽民伟大光辉的一生',
  25. url: 'https://news.ifeng.com/c/8LPwtTX7hsA'
  26. },
  27. ],
  28. },
  29. {
  30. key: 2,
  31. cid: 2,
  32. content: [
  33. {
  34. title: '北京:做好方舱医院治愈患者出院服务保障',
  35. url: 'https://news.ifeng.com/c/8LSoYLjqyFZ'
  36. },
  37. {
  38. title: '北京:做好方舱医院治愈患者出院服务保障',
  39. url: 'https://news.ifeng.com/c/8LSoYLjqyFZ'
  40. },
  41. {
  42. title: '北京:做好方舱医院治愈患者出院服务保障',
  43. url: 'https://news.ifeng.com/c/8LSoYLjqyFZ'
  44. },
  45. ],
  46. },
  47. {
  48. key: 3,
  49. cid: 3,
  50. content: [
  51. {
  52. title: '从爱丽舍宫晚宴到白宫国宴,欧洲看透了美国',
  53. url: 'https://news.ifeng.com/c/8LSyYMJBv1e'
  54. },
  55. {
  56. title: '从爱丽舍宫晚宴到白宫国宴,欧洲看透了美国',
  57. url: 'https://news.ifeng.com/c/8LSyYMJBv1e'
  58. },
  59. {
  60. title: '从爱丽舍宫晚宴到白宫国宴,欧洲看透了美国',
  61. url: 'https://news.ifeng.com/c/8LSyYMJBv1e'
  62. },
  63. ],
  64. },
  65. ];
  66. //创建函数:生成栏目和内容区
  67. function createTab(type, content) {
  68. // 1.生成栏目
  69. for (let i = 0; i < cates.length; i++) {
  70. // 1.1 创建一个按钮
  71. const btn = document.createElement('button');
  72. // 1.2 设置按钮的文本
  73. btn.textContent = cates[i].cname;
  74. // 1.3 给按钮加一个自定义 data-key,主要是为了与内容ID绑定
  75. btn.dataset.key = cates[i].cid;
  76. // 1.4 默认高亮显示第1个,所以第一个加了class='active'
  77. if (i === 0) btn.classList.add('active');
  78. // 1.5 将新按钮,添加到栏目容器元素中 type
  79. type.append(btn);
  80. }
  81. // 2.生成内容
  82. for (let i = 0; i < details.length; i++) {
  83. //2.1 创建列表<ul>
  84. const ul = document.createElement('ul');
  85. //2.2 添加列表索引<ul data-key>
  86. ul.dataset.key = details[i].cid;
  87. //2.3 默认显示第1个,其他隐藏
  88. ul.classList.add(i === 0 ? 'active' : 'hidden');
  89. //2.4 生成子元素<li><a>,用于显示第一条数据
  90. //进入二次循环
  91. for (let k = 0; k < details[i].content.length; k++) {
  92. //生成一个 <li>
  93. const li = document.createElement('li');
  94. //生成一个 <a>
  95. const a = document.createElement('a');
  96. //a.href属性
  97. a.href = details[i].content[k].url;
  98. //a.textContent
  99. a.textContent = details[i].content[k].title;
  100. //将<a>添加到<li>
  101. li.append(a);
  102. //将<li>添加到<ul>
  103. ul.append(li);
  104. //将<ul>添加以.content容器中
  105. content.append(ul);
  106. }
  107. }
  108. }
  109. function setBtnStatus(ev) {
  110. //1.拿到当前按钮
  111. const currentBtn = ev.target;
  112. //2.去掉所有按钮的active,遍历
  113. //ev.currentTarget:事件绑定主体,父元素,转为真数组
  114. // console.log([...ev.currentTarget.children]);
  115. [...ev.currentTarget.children].forEach(btn => btn.classList.remove('active'));
  116. //设置当前按钮高亮
  117. currentBtn.classList.add('active');
  118. }
  119. function setContentStatus(ev,currentBtn){
  120. //1.获取所有列表
  121. const lists = document.querySelectorAll('.content > ul');
  122. //2.去掉所有列表的active,换成hidden
  123. lists.forEach(list => list.classList.replace('active','hidden'));
  124. //3.找到与栏目key对应的列表
  125. //lists:Nodelist对象,不是数组
  126. const currentList =[...lists].find(list => list.dataset.key == currentBtn.dataset.key);
  127. //4.将当前列表高亮
  128. currentList.classList.replace('hidden','active');
  129. }
  130. export { createTab, setBtnStatus, setContentStatus };
Correcting teacher:PHPzPHPz

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