jQuery: това: $(this).next().next() работи, но $(this).next('.div') не

Добре, опитвам се да скрия този набор от информация поотделно.

<img class="arrow" src="images/navigation/arrowright.png">
<H2>More Information</H2>
<div class="box">
    <h2>Bibendum Magna Lorem</h2>
    <p>Cras mattis consectetur purus sit amet fermentum.</p>
</div>

<img class="arrow" src="images/navigation/arrowright.png">
<H2>A Second Group of Information</H2>
<div class="box">
    <h2>Bibendum Magna Lorem</h2>
    <p>Cras mattis consectetur purus sit amet fermentum.</p>
</div>

Работи, когато напиша това:

$(".arrow").click(function() {
    $(this).next().next().slideToggle();
});

но не и когато правя това:

$(".arrow").click(function() {
    $(this).next('.box').slideToggle();
});

Какво се случва, което кара втората опция да не работи? Занимавам се с това от дни и не мога да го проумея! Оценявам приноса ви!


person fjaxyu    schedule 16.05.2015    source източник
comment
FYI, отстъпът на вашия HTML изглежда така, сякаш имате връзки родител/дете между елементи, които всъщност не са там (подвеждащ начин за показване на HTML).   -  person jfriend00    schedule 17.05.2015
comment
ах, да, има смисъл, напълно моя грешка! Аз съм доста нов в това, така че все още свиквам с всичко. Благодаря, че посочихте това!   -  person fjaxyu    schedule 17.05.2015


Отговори (1)


Проблемът

Ако погледнете документацията за .next(selector), тя не „намира“ следващия брат, който съответства на селектора . По-скоро той разглежда САМО следващия брат и връща САМО този елемент, ако съвпада със селектора, което не е това, което искате.

Ето какво казва документът за .next():

Описание: Вземете непосредствено следващия брат или сестра на всеки елемент в набора от съответстващи елементи. Ако е предоставен селектор, той извлича следващия брат само ако съвпада с този селектор.

И така, можете да видите, че .next(".box") ще погледне елемента h2, който непосредствено следва вашия елемент .arrow (това е следващият сроден елемент) и след това ще го сравни със селектора .box и тъй като те не съвпадат, ще върне празен jQuery обект.


Решение, използващо .nextAll()

Ако искате следващия брат, който съответства на селектор, можете да използвате това:

$(this).nextAll(".box").eq(0).slideToggle();

Това намира всички следващи братя и сестри, които съответстват на селектора, и след това извлича само първия.


Създайте свой собствен метод .findNext()

Толкова често съм се чудил защо jQuery няма метод за това, че сам си го създадох:

// get the next sibling that matches the selector
// only processes the first item in the passed in jQuery object
// designed to return a jQuery object containing 0 or 1 DOM elements
jQuery.fn.findNext = function(selector) {
    return this.eq(0).nextAll(selector).eq(0);
}

И тогава просто бихте използвали:

$(this).findNext(".box").slideToggle();

Опция: Добавете повече структура към HTML, за да направите нещата по-прости и по-гъвкави

FYI, общ подход към проблеми като този е да се постави съдържащ div около всеки набор от DOM елементи като този:

<div class="container">
    <img class="arrow" src="images/navigation/arrowright.png">
    <H2>More Information</H2>
    <div class="box">
            <h2>Bibendum Magna Lorem</h2>
            <p>Cras mattis consectetur purus sit amet fermentum.</p>
    </div>
</div>

<div class="container">
     <img class="arrow" src="images/navigation/arrowright.png">
     <H2>A Second Group of Information</H2>
     <div class="box">
            <h2>Bibendum Magna Lorem</h2>
            <p>Cras mattis consectetur purus sit amet fermentum.</p>
     </div>    
</div>

След това можете да използвате код, който е малко по-малко чувствителен към точното позициониране на елементите:

$(".arrow").click(function() {
    $(this).closest(".container").find(".box").slideToggle();
});

Това отива до съдържащия и общ родител, използвайки .closest() и след това използва .find(), за да намери елемента .box в тази група.

person jfriend00    schedule 16.05.2015
comment
по-изразителен: $(this).nextAll(".box").first().slideToggle(); - person Nick Humphrey; 27.03.2017
comment
Повече структура на HTML, за да направите нещата по-прости и по-гъвкави - person HPWD; 16.01.2019