为了账号安全,请及时绑定邮箱和手机立即绑定

嵌套标签系统

嵌套标签系统

斯蒂芬大帝 2021-11-04 17:43:19
当我们单击主菜单中的另一个选项卡并返回到第一个菜单时,第二个菜单(第二个选项卡)失去其活动状态(没有打开的选项卡)此外,is-active链接上的状态被删除。我不知道如何不影响子标签。这是查看问题的链接。<div class="container js-tabs-container">    <div class="tabs">        <ul>            <li class="is-active" data-tab="tab-1"><a>Link 1</a></li>            <li data-tab="tab-2"><a>Link 2</a></li>        </ul>    </div>    <div class="js-tab-content" id="tab-1">        <p>Tab 1</p>        <!-- Nesting tabs -->        <div class="container js-tabs-container">            <div class="tabs">                <ul>                    <li class="is-active" data-tab="tab-2-1"><a>Link 2-1</a></li>                    <li data-tab="tab-2-2"><a>Link 2-2</a></li>                </ul>            </div>            <div class="js-tab-content" id="tab-2-1">              <p>Tab 2-1</p>            </div>            <div class="js-tab-content" id="tab-2-2">              <p>Tab 2-2</p>            </div>        </div>    </div>    <div class="js-tab-content" id="tab-2">        <p>Tab 2</p>    </div></div>document.addEventListener('DOMContentLoaded', function () {  var tabs = document.getElementsByClassName('tabs');  if (tabs) {    var _loop = function _loop() {      var tabListItems = tabs[i].querySelectorAll('.tabs-menu-item');      tabListItems.forEach(function(tabListItem) {        // création d'un écouteur d'évènements sur le clic d'une tab        tabListItem.addEventListener('click', function () {          // suppression de la classe is-active sur chacune des tabs avant de la rajouter sur la tab qui a été cliquée          tabListItems.forEach(function(tabListItem) {            tabListItem.classList.remove('is-active');          });          tabListItem.classList.add('is-active');          // tabName correspond à la valeur de l'attribut data-tab          var tabName = tabListItem.dataset.tab;
查看完整描述

1 回答

?
浮云间

TA贡献1829条经验 获得超4个赞

您遇到的问题是由于您使用querySelectorAllwhich 不仅选择第一层子节点,而且会直接钻入 DOM 并检索所有匹配的节点。一个简单的解决方案可能是通过添加属性来区分子选项卡和父选项卡,并为子项使用单独的处理程序。更全面的方法可能只涉及对顶级选项卡和选项卡内容进行操作。

(为了其他用户的可读性,我在代码中添加了英文注释并删除了外国注释)


'use strict';


document.addEventListener('DOMContentLoaded', function () {


  var tabs = document.getElementsByClassName('tabs');

  if (tabs) {

    var _loop = function _loop() {

      var tabListItems = tabs[i].querySelectorAll('li');


      tabListItems.forEach(function (tabListItem) {


        tabListItem.addEventListener('click', function (e) {


          // Select any siblings of the current tab.

          let siblings = Array.from(tabListItem.parentElement.children);


          // Remove the is-active status from all siblings

          siblings.forEach(function (element) {

            element.classList.remove('is-active');

          });


          // Add the is-active status to the selected tab.

          tabListItem.classList.add('is-active');


          var tabName = tabListItem.dataset.tab;


          // Same as above, rather than selecting all of the js-tab-content

          // elements, we only select those which are at the same level as

          // the selected tab.

          let tabsContainer = tabListItem.closest('.js-tabs-container');

          let tabsContainerChildren = Array.from(tabsContainer.children);


          // Filter out other children that aren't js-tab-content elements.

          let tabs = tabsContainerChildren.filter(function(el) {

            return el.className.includes('js-tab-content')

          });


          tabs.forEach(function(tabContent) {

            if (tabContent.id !== tabName) {

              tabContent.classList.add('has-display-none');

            } else {

              tabContent.classList.remove('has-display-none');

            }

          })


        }, false);

      });

    };


    for (var i = 0; i < tabs.length; i++) {

      _loop();

    }

  }

});

假设您的结构大体保持不变,这对于任何级别的嵌套选项卡都应该正确运行,因为选择选项卡时唯一受影响的项目是它周围的屏幕和链接。


重构


使用箭头函数,并在不需要的地方分配较少的变量将使您能够编写更短更简洁的代码。这是一个示例,不一定是编写它的最佳方式,但它可能会给您一些提取函数和链接数组迭代的想法。


document.addEventListener('DOMContentLoaded', () => {

  Array.from(document.getElementsByClassName('tabs')).forEach(tab => {

    tab.querySelectorAll('li').forEach(listItem => {

      listItem.addEventListener('click', tabClickHandler(listItem), false);

    });

  });

});


function tabClickHandler (listItem) {

  return () => {

    let siblings = Array.from(listItem.parentElement.children);


    siblings.forEach(el => el.classList.remove('is-active'));

    listItem.classList.add('is-active');


    let tabName = listItem.dataset.tab;


    Array.from(listItem.closest('.js-tabs-container').children)

      .filter(el => el.classList.contains('js-tab-content'))

      .forEach(tab => {

        if (tab.id !== tabName) {

          tab.classList.add('has-display-none');

        } else {

          tab.classList.remove('has-display-none');

        }

      });

  }

}


查看完整回答
反对 回复 2021-11-04
  • 1 回答
  • 0 关注
  • 200 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信