views:

643

answers:

1

Hi,

I'm doing quite a bit of DOM manipulation in my app, adding new nodes, and I've found that the children() function can get out of sync. I've got a tbody element with two rows, I use the children() function on this to do some manipulation with these rows. I then add two more rows to the tbody, when I use the children function again to do more manipulation I only get back the original two rows, not these plus the two rows I've just added. I'm doing a new call to children every time, not relying on any variable to auto-update. Is there any way to clear jQuery's cache - I've noticed problems like this a few times with selectors and got around it by selecting further up the DOM tree then navigating back down (i.e. don't select the tbody with a jQuery CSS selector, select the table then do table.tBodies[0].rows), but that won't work in this case.

Thanks, Phil

A: 

The children() function doesn't get out of sync. You have to execute that again if you changed the DOM. On modifying you can have a callback that remakes your array of matched elements. This is not a cache mechanism, is like JavaScript works: linear. Ajax calls are sometimes cached but doesn't seem the case here.

Recommendation Always use the latest version of jQuery: 1.3.2 now.

Update. So this is your code:

function removeGroup() { 
    var groupNodes = [ $('#row1')[0], $('#row2') ];  // is this correct? 
    var parent = groupNodes[0].parentNode; 
    if ( $(parent).children().length > 2) { 
        parent.removeChild(groupNodes[0]); // why not use dirrectly $('#row1')[0].remove();?
        parent.removeChild(groupNodes[1]); // same here
    } else { 
        alert("Can't delete last group"); 
    } 
}

This code has nothing to do with caching and most of it doenst even pass through jQuery. Better explain what you want to do and will do it.

Elzo Valugi
Thanks for your response.Unfortunately, the version of jQuery is forced onto me, I'd update if I could!There is definitely some sort of caching going on, because I am calling $(myNode).children every time, not relying on some old value, but $(myNode).children returns two tr elements whereas $(myNode).rows returns four tr elements. I've given up with the jQuery way for now and just gone to using the rows collection.
sorry - that's myNode.rows, not $(myNode).rows!
can we see a simplified example?
Elzo Valugi
Sure: function removeGroup() {var groupNodes = [ $('#row1')[0], $('#row2') ];var parent = groupNodes[0].parentNode;if ($(parent).children().length > 2) { parent.removeChild(groupNodes[0]); parent.removeChild(groupNodes[1]);} else { alert("Can't delete last group");}}This function gets called when someone clicks a button, but the children() function doesn't seem to reflect the latest version of the DOM tree
ah, forgot it strips out carriage returns here - can you make that out?
it will be a good idea to read the FAQ to see how you can format code, until I take a look :)
Elzo Valugi
Most of it doesn't pass through jQuery, you're right. The 'caching' I was referring to, however, is on the fourth line: `if ( $(parent).children().length > 2) {`. On repeated calls to the function, this always returns the same number, never updating. if I use `$(parent).rows.length` it gives me the correct number. Therefore jquery must be caching the value somehow...
try using $('selector').size() function to get the number of elements, but it should be the same as length. maybe you don't add the element to the dom correctly? try to see what value $(parent).children().length has. This values are not cached. There is something else that you do wrong. Show me the part of code where you add an element.
Elzo Valugi
To add to the dom, I create a document fragment (document.createDocumentFragment), build up my dom tree (mostly via doing a clone(true) on some existing nodes, then individualising id values), then do parent.appendChild(docFragment).
if using jQuery ... use $(parent).append(), or prepend() functions. this will be sure its detected correctly/
Elzo Valugi
ok thanks for that