Как мне удалить класс из любого другого элемента в дереве DOM при нажатии на другой элемент? — jQuery

#javascript #jquery #css

#javascript #jquery #css

Вопрос:

Итак, вот как выглядит мое DOM-дерево:

 <div id="content">
   <div id="sidebar">
      <ul>
          <li class="selected"><a href="#">Header 1</a>
              <ul>
                   <li><a href="#">Link 1</a></li>
                   <li><a href="#">Link 2</a></li>
                   <li><a href="#">Link 3</a></li>
                   <li><a href="#">Link 4</a></li>
              </ul>
          </li>
          <li><a href="#">Header 2</a>
            <ul>
               <li><a href="#">Link 1</a></li>
               <li><a href="#">Link 2</a></li>
            </ul>
          </li>
          <li><a href="#">Header 3</a>
            <ul>
               <li><a href="#">Link 1</a></li>
               <li><a href="#">Link 2</a></li>
            </ul>
          </li>
          <li><a href="#">Header 7</a>
             <ul>
             </ul>
          </li>
          <li><a href="#">Header 4</a>
             <ul>
             </ul>
          </li>
          <li><a href="#">Header 5</a>
            <ul>
              <li><a href="#">Link 1</a></li>
            </ul>
          </li>
      </ul>
   </div>
</div>
  

Итак, когда я хочу выполнить простое addClass и removeClass для одного элемента, это работает:

 $(document).ready(function() {
    $('div#content div#sidebar ul li a').click(function(e) {
        if ($(this).parent().hasClass('selected')) {
            $(this).parent().removeClass('selected');
        }
        else {
            $(this).parent().addClass('selected');
        }        
        e.preventDefault();
    });
});
  

Однако это не удаляет класс selected из каждого «однорангового узла» $(this).parent() . Он удаляет класс только из родительского элемента выбранного в данный момент элемента.

Что я хочу сделать, так это то, что при нажатии на ссылку Header 2 , она добавляет класс selected в Header 2 и проверяет все родственные элементы (в данном случае, li s для ссылок Header 1 - 7 ) и удаляет этот класс для любых родственных элементов, если он его находит. Таким образом, по сути, на этом уровне в DOM-дереве может быть только один класс selected .

Как мне это сделать?

Ответ №1:

 $(function () {
    $('#sidebar > ul > li > a').bind('click', function (e) {
        e.preventDefault();
        $('#sidebar > ul > li').removeClass('selected');
        $(this).parent().addClass('selected');
    });
});
  

При этом выбираются <a> элементы, вложенные в первый уровень <li> элементов, и добавляется .selected класс к его родительскому <li> элементу (при одновременном удалении всех других экземпляров .selected класса).

Вот jsfiddle:http://jsfiddle.net/jasper/RRk25

Это можно было бы оптимизировать:

 $(function () {
    var $first_tier_li = $('#sidebar > ul > li');
    $first_tier_li.children('a').bind('click', function (e) {
        e.preventDefault();
        $first_tier_li.removeClass('selected');
        $(this).parent().addClass('selected');
    });
});
  

Это экономит поиск узлов DOM при каждом нажатии, поскольку они кэшируются с момента возникновения document.ready события.

Вот jsfiddle оптимизации:http://jsfiddle.net/jasper/RRk25/1

Комментарии:

1. Эй, @ Jasper, ты не возражаешь отредактировать это так, чтобы дочерние ul элементы элемента, которые будут удалены, исчезли, или scrollUp, или исчезнут навсегда… в то время как другой показывает себя. Нужно ли мне добавить немного CSS, чтобы получить это, или я могу сделать все это в jQuery?

2. Та правка, которую вы включили об оптимизации, имеет полный смысл, потому что я хочу манипулировать second_tier , так что вы заложили основу для того, чтобы иметь возможность это делать … и это потрясающе.

3. jsfiddle.net/jasper/RRk25/2 , вот так. При этом используются функции .slideUp() и .slideDown() для отображения / скрытия дочерних <ul> элементов. Обратите внимание, что я добавил объявление CSS, чтобы скрыть все <ul> теги второго уровня при загрузке (но я также добавил встроенный CSS в первый «вспомогательный навигатор», <ul> поэтому он отображается по умолчанию).

Ответ №2:

Удалите класс из всех элементов $ (‘div#content div#sidebar ul li’), а затем просто добавьте класс к выбранному. Это сработает для вас?

Смотрите это здесь

Комментарии:

1. Смотрите мою новую правку. Теперь я не уверен, что бы вы хотели делать, когда пользователи нажимают на не заголовки, но это все.