Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Помогите исправить табы (https://javascript.ru/forum/dom-window/85020-pomogite-ispravit-taby.html)

Vaska 08.03.2023 06:31

Помогите исправить табы
 
Приветствую!
На странице есть табы, которые размещены группами по 2 таба в группе.
Есть код JS, который который хорошо работает, если на странице одна группа табов.
А если добавить вторую и третью группу табов, то действия в одной из групп табов влияют на другие группы табов.
Сейчас, если кликнуть по одному табу первой группе, то табы переключаются во второй и в третьей группе. Так быть не должно.
Помогите исправить, чтобы каждый таб переключался независимо друг от друга.
<style>
[data-tab-content] {
  display: none;
}

.active[data-tab-content] {
  display: block;
}

body {
  padding: 0;
  margin: 0;
}

.tabs {
  display: flex;
  justify-content: space-around;
  list-style-type: none;
  margin: 0;
  padding: 0;
  border-bottom: 1px solid black;
}

.tab {
  cursor: pointer;
  padding: 10px;
}

.tab.active {
  background-color: #CCC;
}

.tab:hover {
  background-color: #AAA;
}

.tab-content {
  margin-left: 20px;
  margin-right: 20px;
}
</style>

<ul class="tabs">
  <li data-tab-target="#home1" class="active tab">Home</li>
  <li data-tab-target="#pricing1" class="tab">Pricing</li>
</ul>

<div class="tab-content">
  <div id="home1" data-tab-content class="active">
    <h1>Home 1</h1>
    <p>This is the home 1</p>
  </div>
  <div id="pricing1" data-tab-content>
    <h1>Pricing 1</h1>
    <p>Some information on pricing 1</p>
  </div>
</div>


<ul class="tabs">
  <li data-tab-target="#home2" class="active tab">Home</li>
  <li data-tab-target="#pricing2" class="tab">Pricing</li>
</ul>

<div class="tab-content">
  <div id="home2" data-tab-content class="active">
    <h1>Home 2</h1>
    <p>This is the home 2</p>
  </div>
  <div id="pricing2" data-tab-content>
    <h1>Pricing 2</h1>
    <p>Some information on pricing 2</p>
  </div>
</div>


<ul class="tabs">
  <li data-tab-target="#home3" class="active tab">Home</li>
  <li data-tab-target="#pricing3" class="tab">Pricing</li>
</ul>

<div class="tab-content">
  <div id="home3" data-tab-content class="active">
    <h1>Home 3</h1>
    <p>This is the home 3</p>
  </div>
  <div id="pricing3" data-tab-content>
    <h1>Pricing 3</h1>
    <p>Some information on pricing 3</p>
  </div>
</div>

<script>
const tabs = document.querySelectorAll('[data-tab-target]')
const tabContents = document.querySelectorAll('[data-tab-content]')

tabs.forEach(tab => {
  tab.addEventListener('click', () => {
    const target = document.querySelector(tab.dataset.tabTarget)
    tabContents.forEach(tabContent => {
      tabContent.classList.remove('active')
    })
    tabs.forEach(tab => {
      tab.classList.remove('active')
    })
    tab.classList.add('active')
    target.classList.add('active')
  })
})
</script>


Или подскажите другой скрипт, который умеет делать то, что я выше написал.
Заранее, спасибо!

рони 08.03.2023 07:07

открывашка open tabs
 
Vaska,
<!DOCTYPE HTML>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
        [data-tab-content] {
            display: none;
        }
        .active[data-tab-content] {
            display: block;
        }
        body {
            padding: 0;
            margin: 0;
        }
        .tabs {
            display: flex;
            justify-content: space-around;
            list-style-type: none;
            margin: 0;
            padding: 0;
            border-bottom: 1px solid black;
        }
        .tab {
            cursor: pointer;
            padding: 10px;
        }
        .tab.active {
            background-color: #CCC;
        }
        .tab:hover {
            background-color: #AAA;
        }
        .tab-content {
            margin-left: 20px;
            margin-right: 20px;
        }
    </style>
</head>
<body>
    <ul class="tabs">
        <li data-tab-target="#home1" class="active tab">Home</li>
        <li data-tab-target="#pricing1" class="tab">Pricing</li>
    </ul>
    <div class="tab-content">
        <div id="home1" data-tab-content class="active">
            <h1>Home 1</h1>
            <p>This is the home 1</p>
        </div>
        <div id="pricing1" data-tab-content>
            <h1>Pricing 1</h1>
            <p>Some information on pricing 1</p>
        </div>
    </div>
    <ul class="tabs">
        <li data-tab-target="#home2" class="active tab">Home</li>
        <li data-tab-target="#pricing2" class="tab">Pricing</li>
    </ul>
    <div class="tab-content">
        <div id="home2" data-tab-content class="active">
            <h1>Home 2</h1>
            <p>This is the home 2</p>
        </div>
        <div id="pricing2" data-tab-content>
            <h1>Pricing 2</h1>
            <p>Some information on pricing 2</p>
        </div>
    </div>
    <ul class="tabs">
        <li data-tab-target="#home3" class="active tab">Home</li>
        <li data-tab-target="#pricing3" class="tab">Pricing</li>
    </ul>
    <div class="tab-content">
        <div id="home3" data-tab-content class="active">
            <h1>Home 3</h1>
            <p>This is the home 3</p>
        </div>
        <div id="pricing3" data-tab-content>
            <h1>Pricing 3</h1>
            <p>Some information on pricing 3</p>
        </div>
    </div>
    <script>
        const tabs = document.querySelectorAll('.tabs');
        tabs.forEach(tab => {
            tab.addEventListener('click', ({
                target
            }) => {
                if (target = target.closest('[data-tab-target]')) {
                    let active = tab.querySelector('.active');
                    let id = active.dataset.tabTarget;
                    active.classList.remove('active');
                    document.querySelector(id).classList.remove('active');
                    id = target.dataset.tabTarget;
                    document.querySelector(id).classList.add('active');
                    target.classList.add('active');
                }
            })
        })
    </script>
</body>
</html>

Цитата:

Сообщение от Vaska
Или подскажите другой скрипт, который умеет делать то, что я выше написал.

форум - поиск - открывашка

рони 08.03.2023 07:22

открывашка по индексу
 
Vaska,
тоже самое без dataset, изначально добавьте правильно все классы active.

<!DOCTYPE HTML>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
        .tab-content>div {
            display: none;
        }

        .tab-content>div.active {
            display: block;
        }

        body {
            padding: 0;
            margin: 0;
        }

        .tabs {
            display: flex;
            justify-content: space-around;
            list-style-type: none;
            margin: 0;
            padding: 0;
            border-bottom: 1px solid black;
        }

        .tab {
            cursor: pointer;
            padding: 10px;
        }

        .tab.active {
            background-color: #CCC;
        }

        .tab:hover {
            background-color: #AAA;
        }

        .tab-content {
            margin-left: 20px;
            margin-right: 20px;
        }
    </style>
</head>

<body>
    <ul class="tabs">
        <li class="active tab">Home</li>
        <li class="tab">Pricing</li>
    </ul>
    <div class="tab-content">
        <div class="active">
            <h1>Home 1</h1>
            <p>This is the home 1</p>
        </div>
        <div id="pricing1">
            <h1>Pricing 1</h1>
            <p>Some information on pricing 1</p>
        </div>
    </div>
    <ul class="tabs">
        <li class="active tab">Home</li>
        <li class="tab">Pricing</li>
    </ul>
    <div class="tab-content">
        <div class="active">
            <h1>Home 2</h1>
            <p>This is the home 2</p>
        </div>
        <div>
            <h1>Pricing 2</h1>
            <p>Some information on pricing 2</p>
        </div>
    </div>
    <ul class="tabs">
        <li class="active tab">Home</li>
        <li class="tab">Pricing</li>
    </ul>
    <div class="tab-content">
        <div class="active">
            <h1>Home 3</h1>
            <p>This is the home 3</p>
        </div>
        <div>
            <h1>Pricing 3</h1>
            <p>Some information on pricing 3</p>
        </div>
    </div>
    <script>
        const tabs = document.querySelectorAll('.tabs');
        const content = document.querySelectorAll('.tab-content');
        tabs.forEach((tab, i) => {
            tab.addEventListener('click', ({
                target
            }) => {
                if (target = target.closest('li')) {
                    let active = tab.querySelector('.active');
                    active.classList.remove('active');
                    content[i].querySelector('.active').classList.remove('active');
                    let index = [...tab.querySelectorAll('li')].indexOf(target);
                    target.classList.add('active');
                    content[i].children[index].classList.add('active');
                }
            })
        })
    </script>
</body>

</html>

Vaska 08.03.2023 15:34

Цитата:

Сообщение от рони (Сообщение 551047)
Vaska,
тоже самое без dataset, изначально добавьте правильно все классы active.

Этот вариант для моей задачи лучше подходит, меньше исправлений нужно делать в моём коде.
Но на моей странице, после клика на таб, страница, в браузере, двигается вверх до уровня таба, на который кликнул.
А здесь, на странице, этого не происходит. Здесь всё работает как надо.
Как можно это исправить, чтобы страница не ползла вверх, после клика на таб?
Или хотя бы отступ от топа сделать 80px вниз. Иначе страница ползёт вверх и таб, на который я кликнул, закрывается верхним меню, которое расположено вверху страницы. Таб под меню залазит.

рони 08.03.2023 16:04

Цитата:

Сообщение от Vaska
Как можно это исправить, чтобы страница не ползла вверх, после клика на таб?

не использовать ссылки или так
const tabs = document.querySelectorAll('.tabs');
        const content = document.querySelectorAll('.tab-content');
        tabs.forEach((tab, i) => {
            tab.addEventListener('click', event => {
                let target = event.target;
                event.preventDefault();
                if (target = target.closest('li')) {
                    let active = tab.querySelector('.active');
                    active.classList.remove('active');
                    content[i].querySelector('.active').classList.remove('active');
                    let index = [...tab.querySelectorAll('li')].indexOf(target);
                    target.classList.add('active');
                    content[i].children[index].classList.add('active');
                }
            })
        })

Vaska 08.03.2023 16:12

рони,
Сейчас отлично всё работает.
Большое спасибо, за помощь!


Часовой пояс GMT +3, время: 02:52.