views:

44

answers:

1

I'm trying to write a function in jQuery that will split lists - or really, any element that has children - that is conscious of memory use and is general enough to be widely reusable, but I'm having trouble resolving these against one another.

For the sake of argument (and to keep the code on point) let's say I'm trying to split the list into two lists after element three. I'm not checking my code for syntax errors or anything else - hopefully you get the idea of what I'm trying to do.

Option one is to write a function like this:

var list = $('ul.listCopy');
var newList = $('<ul class="listCopy" />');
var latterElements = list.children('li:gt(3)').remove();
newList.append(latterElements);
list.after(newList);

This is great, but it only works so long as I know the type and attributes of the element. I would have to write a separate function if I were splitting a div with multiple divs inside it, or an OL, or whatever. If the element has a class or a role or any other html attribute, I want to be able to copy it without worrying about what kind of custom attributes might come up in the future. I want to make this general enough to handle any sort of element. This is option two:

var list = //something
var newList = list.clone();
newList.children(':lt(4)').remove();
list.children(':gt(3)').remove();

This is general enough that I could make a copy of anything, but the problem is that I'm making a copy of the entire list. If I were to need to use this program to divide a particularly long list, I'm worried about the memory implications.

The ideal thing I'd like to do is make a copy of an element but only copy the element itself, with none of its children. I don't want to have to copy anything I'm going to end up deleting. Is there a way to do something like this? Most of the plugins and functions I've seen choose one way or the other.

Thanks!

+1  A: 

Use the native cloneNode() method. If you don't pass true as an argument, it doesn't clone any children.

Example: http://jsfiddle.net/4rYxE/

    // Original element
var list = $('ul');
    // Clone of original (top level only)
var newList = list[0].cloneNode();
    // Append children greater than index 3 to the new element
list.children(':gt(3)').appendTo(newList);

Using .appendTo() removes the elements from the original list, and moves them to their new location (in this case, the newList).

patrick dw
That is exactly the method I was looking for - thanks!
sixtimes
@sixtimes - You're welcome. :o)
patrick dw