Yesterday I was writing some jQuery code and I thought I came across a bug—until I realized it was a bug in my way of thinking and not with jQuery.
What I was trying to do is to dynamically append to the body tag some html that looked like this:
The trick was I wanted jQuery to return a reference to the "inner" <div> element.
Knowing that that I could easily append a <div> to the <body> tag by using: $("<div>inner</div>").appendTo("body");, I thought I could just write the following and all would be well:
From looking at the code quickly everything looked ok, but only the <div>inner</div> was being appended to the DOM. This had me confused. I knew that the <div>inner</div> was being inserted into the <div>outer</div>, but why was I not getting the outer <div> in the DOM?
That's when I realized the mistake I made. It's all about the jQuery "chain".
One of the coolest features of jQuery is the ability to "chain" commands together. This allows you to attach multiple commands together with one line of code.
The problem I was having is that I was originally thinking the appendTo() method was changing the jQuery chain to refer to the element that I just appended to. This is incorrect. jQuery always references the first element in the chain, unless you use a command that explicitly changes the chain.
This allows you to write a piece of code that appends an element to multiple elements on a page. The following code would put the string "append me!" in bold print to the end of each <div> and <p> element on the page:
So now that I realized my problem, how could I solve my problem? That part is actually quite simple. I just need to call the parent() method after appending to the <div>outer</div>. This changes the jQuery chain so that it's now referencing the outer <div> instead of the inner <div>.
The end() method is important in my case because I want the variable $inner to be a reference to the first <div> I created. Calling the end() method at the end of the chain, makes jQuery go back to what it was referencing before the parent() method was called. I've used indenting to illustrate when a destructive call has been made.