jQuery: this: “$(this).next().next()” works, but “$(this).next('.div')” does Not

不打扰是莪最后的温柔 提交于 2019-12-04 10:08:28

问题


Okay, I am trying to get this set of information to hide individually.

<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>

It works when I type this:

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

but not when I do this:

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

What is happening that makes the second option not work? I've been at it for days and can't bloody figure it out! I appreciate your input!


回答1:


The Problem

If you look at the documentation for .next(selector), it does not "find" the next sibling that matches the selector. Rather, it looks at JUST the next sibling and ONLY returns that element if it matches the selector which is not what you want.

Here's what the doc for .next() says:

Description: Get the immediately following sibling of each element in the set of matched elements. If a selector is provided, it retrieves the next sibling only if it matches that selector.

So, you can see that .next(".box") will look at the h2 element that immediately follows your .arrow element (that's the next sibling element) and then compare that to the .box selector and since they don't match, it will return an empty jQuery object.


A Solution Using .nextAll()

If you want the next sibling that matches a selector, you can use this:

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

This finds all the siblings that follow that match the selector and then extracts just the first one.


Create Your Own .findNext() Method

I've so often wondered why jQuery doesn't have a method for this that I've made one myself:

// 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);
}

And, then you would just use:

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

Option: Add More Structure to the HTML to Make Things Simpler and More Flexible

FYI, a common approach to problems like this is to put a containing div around each set of DOM elements like this:

<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>

Then, you can use code that is a little less sensitive to exact positioning of elements:

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

This goes up to the containing and common parent using .closest() and then uses .find() to find the .box element in that group.



来源:https://stackoverflow.com/questions/30281166/jquery-this-this-next-next-works-but-this-next-div-does-not

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!