How to select an element's parent and the parent's siblings

JqueryJquery SelectorsCss SelectorsChainingRemoveall

Jquery Problem Overview


I have this code:

$("#test").siblings('p').remove();
$("#test").remove();

How can I chain this code instead of writing it separately?

Jquery Solutions


Solution 1 - Jquery

You want to use addBack() in this case:

$("#test").siblings('p').addBack().remove();


EDIT

Firstly, for future visitors, if you're using jQuery version 1.8-, you're probably need to use andSelf() which is the predecessor of addBack() for compatibility issues.

Secondly, both end and addBack will do the same task in this case but they're actually different perspective. Take a look at this HTML:

<div class="grandpa">
    <div class="dad">
        <div class="son">
            Test
        </div>
    </div>
</div>

If we're using end():

$('.grandpa')
    .find('.dad')
        .find('.son')
        .addClass('youngster')
        .end()
    .addClass('adult')
    .end()
.addClass('oldster');

The result will look like this:

<div class="grandpa oldster">
    <div class="dad adult">
        <div class="son youngster">
            Test
        </div>
    </div>
</div>  

So when we use end() for son, we're telling jQuery that it need to go back from son to parent set which is dad and add class adult.

But when we use addBack:

$('.grandpa')
    .find('.dad')
        .find('.son')
        .addClass('youngster')
        .addBack()
        .addClass('adult')
        .addBack() // This simply do nothing since `addBack` is not traverse up DOM element 
        .addClass('oldster');    

which will result in this:

<div class="grandpa">
    <div class="dad adult oldster">
        <div class="son youngster adult oldster">
            Test
        </div>
    </div>
</div>

So when we call addBack on son, we're telling jQuery to push dad and son into the same room and add new class adult and oldster to both of them.

Solution 2 - Jquery

The end() method is useful primarily when exploiting jQuery's chaining properties. When not using chaining, we can usually just call up a previous object by variable name, so we don't need to manipulate the stack.

The new set of elements is pushed onto a stack that is maintained inside the object. Each successive filtering method pushes a new element set onto the stack. If we need an older element set, we can use end() to pop the sets back off of the stack.

I guess with use of .end() like this:

$("#test").siblings('p').remove().end().remove();

You can find a fiddle


Some explanation:

Now what is happening with this code snippet above:

Suppose this HTML markup:

<div id='container'>
   <div id='test'>This is supposed to be removed.</div>
   <p>And this to be removed too.</p>
</div>

when script executes:

$("#test").siblings('p').remove()

this block removes the sibling item <p> from the view, then markup will be updated like:

<div id='container'>
   <div id='test'>This is supposed to be removed.</div>
</div>

and if we chain it with .end()

$("#test").siblings('p').remove().end()

it gets back to the stack at #test div then the next part of the script gets fired

$("#test").siblings('p').remove().end().remove();
                             //--^^^^^^^^^^^^^^^----this next part

and #test gets removed from the view and your final markup output will be like:

<div id='container'>
</div>

Solution 3 - Jquery

May be off topic.. you can change the view of the problem:

$("#test, #test ~ p").remove(); // !! incorrect way, see comment below

Guys sorry :( my decision isn't correct!!

Selector '~' isn't equal 'sibling'-method. '~' selects all sibling 'p'-elements that follow AFTER the '#test' element.

So i suggest another decision:

$("#test, > p", $('#test').parent()).remove();

It is not enough elegant but the most faster way. Please check it 'http://jsperf.com/how-to-chain-this-code-stackoverflow-16009101'

Performance test result:

Performance test result

PS http://jsfiddle.net/Dpe59/

Solution 4 - Jquery

I have to agree with the comment on the question; for readability and maintainability, use andSelf:

$("#test").siblings('p').andSelf().remove();

Unfortunately, it's been deprecated. But if you're stuck on an older version of jquery like we are, it may be worthwhile.

Solution 5 - Jquery

$("#text").siblings('p').remove().prevObject.remove();

edit: Though this works, don't do this. as Matt's comment says, prevObject is undocumented

Solution 6 - Jquery

$("#test").siblings("p").siblings("#test").remove();

Solution 7 - Jquery

Try this :

$("#test").siblings('p').addBack().remove();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2281332View Question on Stackoverflow
Solution 1 - JqueryEliView Answer on Stackoverflow
Solution 2 - JqueryJaiView Answer on Stackoverflow
Solution 3 - JqueryvladimirView Answer on Stackoverflow
Solution 4 - JqueryIzkataView Answer on Stackoverflow
Solution 5 - Jqueryuser2153497View Answer on Stackoverflow
Solution 6 - JqueryMihai B.View Answer on Stackoverflow
Solution 7 - Jqueryuser2266451View Answer on Stackoverflow