2010-05-11 39 views
2

我想使用document.createDocumentFragment()創建一個包含來自jQuery(v 1.4.2)的「.data」的HTML元素的優化集合,但我是有種如何從HTML元素中獲取數據的問題。使用document.createDocumentFragment()包含jQuery.data的子DOM元素

這裏是我的代碼:


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); 

什麼我錯在這裏做什麼?我懷疑這可能是.cloneNode()在元素被追加到documentFragment時不攜帶數據的東西。有時候會有很多行,所以我想讓事情保持優化,速度明智。

謝謝!

回答

1

您在jQuery對象上運行cloneNode。你從本地API開始,然後將其轉換爲jQuery對象,然後切換回來。

我想你可以這樣做:

genres_html.appendChild(genre.get(0).cloneNode(true)); 

但我懷疑你會失去你的data


編輯:

如果你想jQuery的,而不是創建一個片段,嘗試創建一個空的jQuery對象,然後推動各流派進去:

var genres_html = $(); 
... 
genres_html.push(genre); 

編輯:

試試這個。我不是DOM專家,但它可能適合你。

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')); 

讓我知道它是否有效。

編輯:改變了我的錯誤與innerHTML的

EDIT2:使用本機innerHTML來追加到#list

+0

是的,我認爲這是我很困惑的主要部分,我不知道我是否想從一個jQuery對象開始或不。我在看這張幻燈片,但它是純JS:http://ejohn.org/apps/workshop/adv-talk/#6 - 我需要的是基本上將它轉換爲一個jQuery對象,它包含元素數據。 – taber 2010-05-11 19:15:11

+0

你可以使用原生的'setAttribute'和'innerHTML'函數,但是如果你需要使用jQuery的'data()',顯然你需要一個jQuery對象。所以問題是,*你真的需要使用'數據'*嗎?也許你可以設置自定義屬性。我會用可能性更新我的答案。 – user113716 2010-05-11 19:20:42

+0

謝謝,是的問題是我無法追加一個「jQuerified」documentElement(包含數據)到我的documentFragment。是的,我想使用'數據'。 :( – taber 2010-05-11 19:23:49

1

對不起,我也不是很清楚 - 我想用documentFragments的性能增益,但的「潔淨」 jQuery的。 :)雖然令人敬畏,但我想我明白了!


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); 

非常感謝幫助!當我將它追加到documentFragment時,我認爲問題是遺漏.get(0)。它像.get(0)一樣也返回完整的數據!

績效收益仍然待定。我知道jQuery 1.4使用documentFragments,但不完全確定哪裏/哪些方法。至少現在這個工程雖然! :)

+1

如果您正在尋找性能提升,您首先需要繞過創建jQuery對象,以及使用jQuery的API。所有這些只是本機API的抽象,並且只會減慢你的代碼。如果性能可以接受,那麼不妨使用jQuery。如果你需要改進,那麼去本地。使用'documentFragment'可能不會比填充空的jQuery對象更有幫助,因爲jQuery可能會創建自己的片段。 – user113716 2010-05-11 22:06:34

+1

好點!儘管在這一點上開始jQuery是不成問題的。 :DI將字母'h'的快速基準測試組合成一個0-1000的快速基準測試,並將它們附加到一個div中... 1)使用上面的方法(jQuery和document.createDocumentFragment),2)在每一箇中使用jQuery.append迭代for循環,以及3)使用document.createDocumentFragment而不使用jQuery。以下是結果示例:1)922ms,2)1547ms,3)828ms。因此,對於約600毫秒的節省,我會選擇第一個選項。 :D感謝您的新的documentElement創建語法! 1.4是好東西。 – taber 2010-05-12 00:57:19

相關問題