Using document.createDocumentFragment () child dom elements containing jQuery.data
I want to use document.createDocumentFragment()
to create an optimized collection of HTML elements containing ".data" coming from jQuery (v 1.4.2), but I'm kind of stuck on how to get data to the surface from HTML elements.
Here's my code:
var genres_html = document.createDocumentFragment();
$(xmlData).find('genres').each(function(i, node) {
var genre = document.createElement('a');
$(genre).addClass('button')
.attr('href', 'javascript:void(0)')
.html( $(node).find('genreName:first').text() )
.data('genreData', { id: $(node).find('genreID:first').text() });
genres_html.appendChild( genre.cloneNode(true) );
});
$('#list').html(genres_html);
// error: $('#list a:first').data('genreData') is null
alert($('#list a:first').data('genreData').id);
What am I doing wrong here? I suspect that maybe something with is .cloneNode()
not transferring data when an item is added to documentFragment
. There are multiple lines sometimes, so I want things to be pretty optimized for speed.
Thanks!
a source to share
You are using cloneNode
jQuery for the object. You start with a native API, then convert it to a jQuery object and then shutdown.
I suppose you could do:
genres_html.appendChild( genre.get(0).cloneNode(true) );
But then I suspect you will lose yours data
.
EDIT:
If you want jQuery, instead of creating a snippet, try creating an empty jQuery object and then inserting each genre into it:
var genres_html = $();
...
genres_html.push( genre );
EDIT:
Try it. I'm not a DOM expert, but this might work for you.
var genres_html = document.createDocumentFragment();
$(xmlData).find('genres').each(function(i, node) {
var genre = document.createElement('a');
genre.setAttribute('class','button');
genre.setAttribute('href', 'javascript:void(0)');
var $node = $(node);
genre.setAttribute('genreData', $node.find('genreID:first').text() );
genre.innerHTML = $node.find('genreName:first').text();
genres_html.appendChild( genre.cloneNode(true) ); // Not sure why you would need to make a clone??
});
var list = document.getElementById('list');
list.appendChild(genres_html);
// error: $('#list a:first').data('genreData') is null
alert($('#list a:first').attr('genreData'));
Let me know if it works.
EDIT: Changed my error with innerHTML
EDIT2: Using native innerHTML to add to #list
a source to share
Sorry I was not very clear - I want to improve the performance of using documentFragments, but the jQuery "clean". :) Surprising, although I think I figured it out!
var genres_list = document.createDocumentFragment();
$(xmlData).find("genres").each(function(i, node) {
genres_list.appendChild(
$('<a></a>').addClass('button')
.attr('href', 'javascript:void(0)')
.html('Anchor Text Here')
.data('genreData', {id: 2000})
.get(0) // ah-ha!
)
);
});
$('#list').append(genres_list);
// alerts 2000
alert($('#list').find('a:first').data('genreData').id);
Thanks for the help! I think the problem was the missing .get (0) when adding it to the documentFragment. It loks like .get (0) returns data unchanged too!
Productivity growth is still TBD. I know jQuery 1.4 uses documentFragments, but doesn't know exactly where / which methods. At least it works now! :)
a source to share