Этот пост предоставляет ванильное решение JavaScript для инициализации вкладок с вкладками в начальной загрузке. Традиционно бутстрап в значительной степени полагается на плагины jQuery, и существует ряд причин, по которым разработчик может вообще не использовать jQuery. Я кратко (я попробую, хе-хе) коснусь этого, прежде чем перейти непосредственно к коду.

В прошлом веб-браузеры доставляли много хлопот, потому что не существовало последовательного способа работы с DOM API. Встроенный DOM API различается между браузерами, и JQuery был исключительным решением этой проблемы, предоставляя простой API, который хорошо работал во всех основных браузерах. Кроме того, библиотека предоставила разработчикам простые средства для просмотра и управления HTML-документами.

За прошедшие годы все основные браузеры развились, и, в отличие от прошлого, реализация DOM API во всех браузерах значительно согласована. Polyfills были разработаны для облегчения написания программного обеспечения для современных браузеров, но при этом могут поддерживать старые.

Современные фреймворки, такие как REACT, также абстрагированы и автоматизировали манипуляции с DOM, что делает почти ненужным использование специализированной библиотеки манипуляций с DOM. В том случае, если нужно вручную возиться с DOM, будет достаточно собственного DOM API.

Хорошие ребята из HubSpot задокументировали некоторые общие функции jQuery и их чистый эквивалент JavaScript. Проверьте это!

Разработчикам, которые хотят использовать веб-компоненты, в частности теневую DOM, рекомендуется не использовать плагины jQuery, поскольку они запрашивают элементы на уровне документа. Это неизбежно приведет к сбою при запросе чего-то внутри теневого корня, потому что он инкапсулирует DOM, создавая теневую границу, которая блокирует это действие на уровне документа, что приводит к досадным ошибкам, которые сведут вас с ума! Подробнее об этом можно прочитать здесь.

Я работаю над сторонним виджетом, который использует теневую DOM, и мне нужно было использовать компонент вкладок начальной загрузки. Просматривая документацию, они предоставили простой фрагмент, который включает вкладки с вкладками через JavaScript, как показано ниже:

Вкладки навигации Bootstrap HTML

<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="home-tab" href="#home">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" id="profile-tab" href="#profile">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" id="messages-tab"href="#messages">Messages</a>
</li>
<li class="nav-item">
<a class="nav-link" id="settings-tab"href="#settings">Settings</a>
</li>
</ul>

Добавьте панели вкладок сразу после

<div class="tab-content">
<div class="tab-pane active" id="home" role="tabpanel" aria-labelledby="home-tab">a</div>
<div class="tab-pane" id="profile" role="tabpanel" aria-labelledby="profile-tab">b</div>
<div class="tab-pane" id="messages" role="tabpanel" aria-labelledby="messages-tab">c</div>
  <div class="tab-pane" id="settings" role="tabpanel" aria-labelledby="settings-tab">d</div>
</div>

Оживите приведенный выше HTML, сделав его вкладками. Реализация jQuery в Bootstrap

$('#myTab a').on('click', function (e) {
  e.preventDefault()
  $(this).tab('show')
})

Как видите, приведенный выше фрагмент сильно загружен jQuery и, очевидно, не будет работать с теневой DOM из-за характера спецификации, поэтому я быстро принял решение написать функциональность на ванильном JavaScript. Это на пару строк длиннее (ну вроде как), но избавило меня от головной боли.

Наконец, ванильная реализация JavaScript !!! :-)

const myTabs = document.querySelectorAll("ul.nav-tabs > li > a");  
const panes = document.querySelectorAll(".tab-pane");
const tabAction = Object.keys(myTabs).map((tab)=>{
            myTabs[tab].addEventListener("click", (e)=> {
             
                    makeInactive(myTabs);
                    activateTab(e);
                    makeInactive(panes);
                    activateTabContent(e);
                   
                    e.preventDefault();
                });
});
             
   /*
    *Makes a tab and it's content incactive
    */
   function makeInactive(items) {
                 
      const  content = Object.keys(items).map((item)=> {
               
              items[item].classList.remove("active");
                    
                 });  
                 
             }
             
    /*
     *Display the selected tab.
     */
   function activateTab(e) {
                 
  //refers to the element whose event listener triggered the event
       const clickedTab = e.currentTarget;
       clickedTab.classList.add("active");
                 
 }
             
  /*
   * Display the selected tab content.
   */
  function activateTabContent(e) {
                 
   // gets the element on which the event originally occurred
       const anchorReference = e.target;
       const activePaneID = anchorReference.getAttribute("href");
       const activePane = document.querySelector(activePaneID);
       activePane.classList.add("active");     
                 
 }

Я думаю, что это довольно просто, но в любом случае я опубликую полный пример на моем github (может быть, завтра). Надеюсь это поможет :-)