Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have a list of elements (well, nested lists of elements, really) that the user can reorder (using jQuery sortable()). A simplified view of the structure is something like:

<div class="contentList">
    <div class="content" />
    <div class="content">
        <div class="contentListInner">
            <div class="triggerContent" />
            <div class="triggerContent" />
            <div class="triggerContent" />
        </div>
        <div class="contentListInner">
            <div class="triggerContent" />
            <div class="triggerContent" />
            <div class="triggerContent" />
        </div>
    </div>
    <div class="content" />
        <div class="contentListInner">
            <div class="triggerContent" />
            <div class="triggerContent" />
            <div class="triggerContent" />
        </div>
        <div class="contentListInner">
            <div class="triggerContent" />
            <div class="triggerContent" />
            <div class="triggerContent" />
        </div>
    <div class="content" />
    <div class="content" />
</div>

Each .content inside of .contentList is sortable, and each .triggerContent inside of .contentListInner is also sortable (independently of the other sections). Each element within these sections is numbered according to its position in its own list. So to continue with the example above, the correct numbering is:

<div class="contentList">
    <div class="content" /> <!-- 1 -->
    <div class="content">   <!-- 2 -->
        <div class="contentListInner">
            <div class="triggerContent" /> <!-- 1 -->
            <div class="triggerContent" /> <!-- 2 -->
            <div class="triggerContent" /> <!-- 3 -->
        </div>
        <div class="contentListInner">
            <div class="triggerContent" /> <!-- 1 -->
            <div class="triggerContent" /> <!-- 2 -->
            <div class="triggerContent" /> <!-- 3 -->
        </div>
    </div>
    <div class="content" /> <!-- 3 -->
        <div class="contentListInner">
            <div class="triggerContent" /> <!-- 1 -->
            <div class="triggerContent" /> <!-- 2 -->
            <div class="triggerContent" /> <!-- 3 -->
        </div>
        <div class="contentListInner">
            <div class="triggerContent" /> <!-- 1 -->
            <div class="triggerContent" /> <!-- 2 -->
            <div class="triggerContent" /> <!-- 3 -->
        </div>
    <div class="content" /> <!-- 4 -->
    <div class="content" /> <!-- 5 -->
</div>

There's an additional complication, in that each .triggerContent can contain a new repetition of the entire structure, beginning again from .contentList. This nested content, however, is essentially spurious and should be ignored for all practical purposes.

Anyhow, to apply the numbering to the inner sections (and simultaneously ignore content in the aforementioned nested sections), I'm currently using the following code:

$(".contentListInner").each(function() {
    var taskNum = 1;
    $(this).find(".triggerContent .taskTitle .left .number").each(function() {
        if ($(this).parents(".triggerContent").length == 1) {
            //FIXME:  filtering on parents() is *slow*; find a faster approach
            $(this).text("Task " + taskNum);
            taskNum++;
        }
    });
});

This works, but as the FIXME notes I found that filtering using .parents() is incredibly slow. If I don't filter on .parents(), then what happens is that nested .triggerContent instances affect the count, and the numbering is incorrect (numbers jump like 1, 8, 17, 32, etc.).

Can anyone suggest an alternate approach that will produce the same results without the performance hit?

share|improve this question
add comment

1 Answer

up vote 4 down vote accepted

Try using the children selector: http://api.jquery.com/children/.

This only retrieves the first set of nested items (one level down vs. find which goes all the way down). I'm not sure how you're nested exactly with your other classes, but it would be something like this.

$(".contentListInner").each(function() {
    $(this).children(".triggerContent").each(function(index, element) {
       $(element).text("Task " + (index + 1));
    });
});
share|improve this answer
    
Thanks, I had to go through a couple sets of children() to get this to work with the actual page structure, but that still seems faster than filtering using the result of parents(). –  aroth Feb 20 '13 at 3:38
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.