views:

55

answers:

1

Turns out jQuery's "implicit looping" goes both way:

    <div class="classOne">
        some content
    </div>

    <div class="classOne">
        some content 2
    </div>  

[...]

$(function() { $('hello world').prependTo($('.classOne')); })

in this case, the loop will happen at the $('.classOne') section -- hello world will be added to both Divs.

I also tried

    <div class="classOne">
        some content
    </div>

    <div class="classOne">
        some content 2
    </div>  

    <div class="classTwo">
        <a href="http://www.google.com"&gt;hello Google</a>
    </div>

    <div class="classTwo">
        <a href="http://www.yahoo.com"&gt;hello Yahoo</a>
    </div>  

[...]

$(function() { $('.classTwo').prependTo($('.classOne')); })

and there will be "nested loops"... so the 2 links will be added to both Divs

so i think if we have

$('.classOne').prepend($('.classTwo')).prepend($('.classThree'))

then it will be like 3 nested loops? Is there a rule to the nesting, and which one is the inner loop and which one is the outer loop? And what is the inner loop / outer loop if it is

$('.classOne').prependTo($('.classTwo')).prependTo($('.classThree'))

?

+2  A: 

Each predecessor to the .prependTo() will be appended to each item passed to the in, you can see the actual jQurey core code here. Since you're passing a jQuery object to the .prependTo(), it'll look through each of those elements and add a cloned version of each object in the chain preceeding the prepend.

So each .prependTo() = one for loop (when passing a jQuery object in), but they're not nested. The results of one are just passed to the next, but it's an array that gets gets elements pushed on it, you can use .end() to return to the previous array for example.

I apologize if that's not a crystal clear explanation, I realize it's a bit weird t think about with the chaining...but if you can specify any questions this leaves in comments I'll try and update to address any confusion/part-I-missed specifically.

Nick Craver
@Nick - I have a question or two if you don't mind. Given this example http://jsfiddle.net/9Wdqf/ and your explanation, I would expect a different result. Would you mind having a look and telling me what you think? I gave an explanation of my expectation in the jsFiddle.
patrick dw
@patrick - The result is correct...the first prepend adds the elements to the `.classTwo`, but also pushes those element references onto the set you're working with (I agree that's the confusing bit), then *that* set is prepended to `.classThree`, which *moves* those elements again, so you've moved the first set of elements *and* the ones that were pushed onto the array in the first prepend as well...and they all end up prepended to `.classThree`, make sense?
Nick Craver
so there will be 8 classOne elements... the effect of 2 x 2 x 2...
動靜能量
@Nick - That is the result I would expect, but the `.classTwo` elements don't move. They seem to stay in their original place instead of getting appended to `.classThree` with the `.classOne` elements. Makes sense to me that `.classOne` would get moved twice, but I don't understand why `.classTwo` doesn't move into `.classThree`.
patrick dw
@Jian - That part I understand. But I would expect the `.classTwo` elements to be moved into the `.classThree` elements, ending up with 4 `.classTwo` elements (2 x 2).
patrick dw
@patrick - The `.classTwo` elements weren't in the chain, so they were never pushed on the array...look at the chain, it's saying prepend *these* elements to `.classTwo`, ok now prepend all *those* to `.classThree`...but `.classTwo` never entered into the equation, the elements that *were* in there are just innocent bystanders. For example: `$('#myDiv').prependTo('body').prependTo('#anotherDiv')`...would you expect everything else in the `<body>` to go to `#anotherDiv`?
Nick Craver
@Nick - I read up to the comma above, and it hit me. The original set is returned, not the element passed into the `prependTo()`. Ugh. Sorry... and thanks. :o)
patrick dw
For any that are interested in a stranger illustration to see the consistent behavior, here's @patrick's demo updated with `.end()` to move the original set: http://jsfiddle.net/9Wdqf/2/ The *original* elements end up at the end x2 because there are 2 `.classFour` so the `.prepend('.classFour')` runs against both, on the others they're removed, because the `.end()` causes those specific references/elements to be prepended to the next guy, their clones (on different sets) left behind.
Nick Craver