博客列表 >【JS】模块实战:经典选项卡=>重点,可直接应用项目

【JS】模块实战:经典选项卡=>重点,可直接应用项目

可乐随笔
可乐随笔原创
2022年12月04日 17:06:34298浏览

模块实战:经典选项卡

总结:

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