Jquery добавление классов при событии

Есть три основные строки. По клику по основной строке выпадает скрытый ранее список, на нее накладывается класс --active, а на остальные главные строки класс opacity. Проблема в том что если открывать еще одну основную строку, класс opacity начинает накладываться уже на активные строки и слетает у третьей строки (в примере видно что происходит). Подскажите алгоритм чтобы избежать этого. Должна быть возможность открывать сразу несколько вкладок и при закрытии всех вкладок, все должно прийти к дефолтному состоянию.

https://jsfiddle.net/6dgxv74n/

к сожалению не знаю как добавить код jquery, так что рабочий пример в ссылке

.main {
  padding: 5px 10px;
  background-color: #fff;
  border: 1px solid #333;
  border-radius: 12px;
}

.main--active {
  background-color: #ccc;
}
.opacity {
  opacity: 0.4;
}
<div class="main">main row</div>
  <ul class="hidden">
    <li>subrow</li>
    <li>subrow</li>
    <li>subrow</li>
    <li>subrow</li>
  </ul>
<div class="main">main row</div>
  <ul class="hidden">
    <li>subrow</li>
    <li>subrow</li>
    <li>subrow</li>
    <li>subrow</li>
  </ul>
<div class="main">main row</div>
<ul class="hidden">
  <li>subrow</li>
  <li>subrow</li>
  <li>subrow</li>
  <li>subrow</li>
</ul>


Ответы (3 шт):

Автор решения: DaemonHK

Если очень быстро, по простому и я правильно понял: https://jsfiddle.net/y21evzbt/2/

Всегда оборачивайте дочерние элементы в отдельные блоки, потом меньше проблем будет

$(document).ready(function(){
    $('.menu').each(function(){
    var item = $(this);
    item.find('.main').off('click').on('click', function(){
        $('.menu').removeClass('main--active').addClass('opacity');
      $('.menu').find('.hidden').removeClass('show');
        item.toggleClass('main--active').removeClass('opacity');
        item.find('.hidden').toggleClass('show');
    });
  });
})
.main {
  background-color: #fff;
  border: 1px solid #333;
  border-radius: 12px 12px 0 0;
}

.main--active {
  background-color: #ccc;
}
.opacity {
  opacity: 0.4;
}
.hidden{
  display:none;
}
.show{
  display:block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="menu">
  <div class="main">main row</div>
  <ul class="hidden">
    <li>subrow</li>
    <li>subrow</li>
    <li>subrow</li>
    <li>subrow</li>
  </ul>
</div>
<div class="menu">
  <div class="main">main row</div>
  <ul class="hidden">
    <li>subrow</li>
    <li>subrow</li>
    <li>subrow</li>
    <li>subrow</li>
  </ul>
</div>
<div class="menu">
  <div class="main">main row</div>
  <ul class="hidden">
    <li>subrow</li>
    <li>subrow</li>
    <li>subrow</li>
    <li>subrow</li>
  </ul>
</div>

→ Ссылка
Автор решения: InDevX

$(document).ready(function(){
let opened = 0;
  $('.main').click(function () {
    // удаляем клас у всех div.main
    $('.main').removeClass('main--active');
    // если ul текущего div.main не имеет класса shown
    if ( !$(this).next(".hidden").hasClass("shown") ) {
      // добавляем текущему div.main клас
      $(this).addClass('main--active');
    }
    // "открываем" текущий ul эл-т
    $(this).next(".hidden").slideToggle("slow");
    // добавляем/удаляем класс для отслеживания
    // открытых меню, напр. класс shown
    $(this).next(".hidden").toggleClass("shown");
    // проверяем кол-во видимых ul
    if ( $('.shown').length ) {
      // добавляем класс всем div.main 
      $('.main').addClass('opacity');
    } else {
      // удаляем все .opacity
      $('.main').removeClass('opacity');
    }
    // удаляем класс у текущего div.main
    $(this).removeClass('opacity');
  });
})
.main {
  background-color: #fff;
  border: 1px solid #333;
  border-radius: 12px 12px 0 0;
  cursor: pointer;
}
.main:not(.main--active) + ul {
  opacity: 0.4;
}
.main--active {
  background-color: #ccc;
}
.opacity {
  opacity: 0.4;
}
.hidden {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">main row</div>
<ul class="hidden">
  <li>subrow</li>
  <li>subrow</li>
  <li>subrow</li>
  <li>subrow</li>
</ul>
<div class="main">main row</div>
<ul class="hidden">
  <li>subrow</li>
  <li>subrow</li>
  <li>subrow</li>
  <li>subrow</li>
</ul>
<div class="main">main row</div>
<ul class="hidden">
  <li>subrow</li>
  <li>subrow</li>
  <li>subrow</li>
  <li>subrow</li>
</ul>

→ Ссылка
Автор решения: Meth0d

Решение

$(document).ready(function(){
  $('.main').click(function () {
    $(this).next(".hidden").slideToggle("slow");
    $(this).toggleClass('main--active');        
    $('.main').css('opacity',0.4);
    $('.main.main--active').css('opacity',1);
    if ($('.main.main--active').length == 0) {
      $('.main').css('opacity',1);
    }
  });
})
.main {
  background-color: #fff;
  border: 1px solid #333;
  border-radius: 12px 12px 0 0;
  cursor: pointer;
}
.main--active {
  background-color: #ccc;
}
.hidden {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">main row</div>
<ul class="hidden">
  <li>subrow</li>
  <li>subrow</li>
  <li>subrow</li>
  <li>subrow</li>
</ul>
<div class="main">main row</div>
<ul class="hidden">
  <li>subrow</li>
  <li>subrow</li>
  <li>subrow</li>
  <li>subrow</li>
</ul>
<div class="main">main row</div>
<ul class="hidden">
  <li>subrow</li>
  <li>subrow</li>
  <li>subrow</li>
  <li>subrow</li>
</ul>

→ Ссылка