Выберите предыдущие заголовки, которые не являются родительскими для текущего элемента / jQuery

#jquery #html #select #html-heading

#jquery #HTML #выберите #html-заголовок

Вопрос:

У меня есть следующая разметка

 <div id="section1">
  <h1>Titel 1</h1>
  <p>Some smart Text</p>
</div>
<div id="section2"> 
  <h2>Titel 2</h2>
  <p>Some smart Text2</p>
</div>
<div id="section3-1">
  <h3>Titel 3-1</h3>
</div>
<div id="section3-1content">
  <ul>
     <li id="section3-1content-el1">El1</li>
     <li id="section3-1content-el2">El2</li>
  </ul>
</div>
<div id="section3-2">
  <h3>Titel 3-2</h3>
</div>
<div id="section3-2content">
  <ul>
     <li id="section3-2content-el1">El1</li>
     <li id="section3-2content-el2">El2</li>
  </ul>
</div>
  

Когда я нажимаю на #section3-2content-el2, я хочу вернуться

  <h3>Titel 3-2</3>
  

(ближайший h3), затем

  <h2>Titel 2</h2> 
  

и затем

  <h1>Titel 1</h1>.
  

Проблема в том, что h3, h2 и h1 на самом деле не являются родительскими для выбранного элемента. Есть ли какой-либо способ вернуться в исходный код и найти первый h3, затем первый h2, а затем первый h1?

Проблема с:

 $('#section3-2content-el1').click(function(){
  $('#section3-2content-el1').parents('h3');
  $('#section3-2content-el1').prevAll('h3');
  $('#section3-2content-el1').closest('h3');
});
  

заключается в том, что все они перемещаются вверх по dom и смотрят, является ли один из них h3. Но h3 не является родительским для выбранного элемента.

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

1. попробуйте .closest() . Если это действительно ПЕРВОЕ, что вы хотите, вы можете использовать $('h3:first') и т.д..

2. Вы также можете использовать api.jquery.com/nth-child-selector

3. .closest() не работает. Мне не нужен первый h3, мне нужен первый h3, предшествующий выбранному элементу в исходном коде, но этот h3 не является родительским для выбранного элемента. prev(), closest() и prevAll() просто перемещаются по иерархии dom и не могут найти h3.

4. @SimonS. Почему вы не используете идентификатор? Я вижу, что выбранный элемент частично имеет родительский идентификатор h3.

5. Потому что разметка html намного сложнее, и у меня нет идентификатора. Я просто придумал это, чтобы проиллюстрировать свою точку зрения.

Ответ №1:

Демонстрационная скрипка

Есть много вариантов. Рассмотрение вашей структуры html :last — лучший вариант. Проверьте демонстрацию.

 $(this).parents('body').find('h3:last')
  

Если бы ваши теги заголовков были согласованными, .prev() был бы другой вариант.

Ответ №2:

Я бы сделал это, используя .map() метод jQuery для возврата массива (или, в любом случае, типа массива) имен классов. Затем вы можете сопоставить имя класса выбранного элемента с заголовком, который разделяет его имя класса.

Сначала добавьте некоторые классы к <h3> s и <li> s:

 <div id="section1">
    <h1>Titel 1</h1>
    <p>Some smart Text</p>
</div>
<div id="section2"> 
    <h2>Titel 2</h2>
    <p>Some smart Text2</p>
</div>
<div id="section3-1">
    <h3 class="first">Titel 3-1</h3>
</div>
<div id="section3-1content">
    <ul>
        <li id="section3-1content-el1" class="first">El1</li>
        <li id="section3-1content-el2" class="first">El2</li>
    </ul>
</div>
<div id="section3-2">
    <h3 class="second">Titel 3-2</h3>
</div>
<div id="section3-2content">
    <ul>
        <li id="section3-2content-el1" class="second">El1</li>
        <li id="section3-2content-el2" class="second">El2</li>
    </ul>
</div>
  

И JS / jQuery:

 $(document).ready(function(){
    $('li').click(function(){
        var self = $(this);

        // Create an array of class names
        var cls = $('h3').map(function(){
            return $(this).attr('class');
        });

        // Loop through the array until the current iteration matches the class name of the clicked element
        for (var i = 0; i < cls.length; i  ) {
            if (self.hasClass(cls[i])) {

                // Do stuff based on whether there is a match
                alert($('h3.'   cls[i]).attr('class'));
            }
        }
    });
});
  

СКРИПКА: http://jsfiddle.net/KFS4E /