2010-05-11 2 views
2

Я хочу использовать document.createDocumentFragment() для создания оптимизированной коллекции элементов HTML, содержащих «.data», исходящие из jQuery (v 1.4.2), но я вид застрял в том, как получить данные на поверхность из элементов HTML.Использование document.createDocumentFragment() дочерних элементов dom, содержащих jQuery.data

Вот мой код:


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

Вы используете cloneNode объект jQuery. Вы начинаете с родного API, а затем конвертируете его в объект jQuery, а затем переключаете обратно.

Я полагаю, вы могли бы сделать:

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

Но я подозреваю, что вы потеряете data.


EDIT:

Если вы хотите JQuery, вместо того, чтобы создать фрагмент, попробуйте создать пустой объект JQuery, то толкая каждый жанр в него:

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

EDIT:

Попробуйте. Я не эксперт 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')); 

Сообщите мне, если это будет работать.

EDIT: изменил мою ошибку с innerHTML

EDIT2: Использование родного innerHTML для добавления к #list

+0

Да, я думаю, что это основная часть, с которой я смущен, я не знаю, хочу ли я начать с объекта jQuery или нет. Я смотрел этот слайд, но это просто JS: http://ejohn.org/apps/workshop/adv-talk/#6 - мне нужно, чтобы в основном преобразовать это в объект jQuery, в котором хранятся данные элемента , – taber

+0

Вы можете использовать собственные функции 'setAttribute' и' innerHTML', но если вам нужно использовать 'data()' jQuery, то, очевидно, вам понадобится объект jQuery. Так что вопрос: * действительно ли вам нужно использовать «данные» *? Возможно, вы могли бы установить настраиваемый атрибут. Я могу обновить свой ответ с возможностью. – user113716

+0

Спасибо, да, проблема в том, что я не могу добавить элемент документа jQuerified (содержащий данные) к моему документу. Да, я хотел бы использовать «данные». :( – taber

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

Спасибо за тонну за помощь! Я думаю, проблема заключалась в отсутствии .get (0) при добавлении его в documentFragment. Он loks как .get (0) также возвращает данные нетронутыми!

Показатели производительности по-прежнему являются TBD. Я знаю, что jQuery 1.4 использует documentFragments, но точно не знает, где/какие методы. По крайней мере, сейчас это работает! :)

+1

Если вы ищете прирост производительности, вам необходимо обойти создание объекта jQuery в первую очередь, а также использование API jQuery. Все это всего лишь абстракция собственного API, и только замедлит ваш код. Если производительность приемлема, тогда также можно использовать jQuery. Если вам нужны улучшения, перейдите на русский язык. Использование 'documentFragment', вероятно, не поможет ничего, кроме заполнения пустого объекта jQuery, поскольку jQuery скорее всего создает собственный фрагмент. – user113716

+1

Если вы хотите какой-нибудь действительно приятный jQuery, сделайте это '$ ('', {'class': 'button', 'href': 'javascript: void (0)', 'text': 'Anchor text here'}) .data ('genreData', {id: 2000}). get (0) ' – user113716

+1

Хорошая точка! Однако в этом случае вопрос о jQuery в этом вопросе не может быть и речи. : DI собрал быстрый контрольный тест, составляющий 0-1000, к букве «h» и добавив их в div ... 1) используя мой метод выше (jQuery с document.createDocumentFragment), 2) используя jQuery.append в каждом итерация цикла for и 3) использование document.createDocumentFragment без jQuery. Вот пример результатов: 1) 922ms, 2) 1547ms, 3) 828ms. Так что за экономию ~ 600 мс я собираюсь с первым вариантом. : D Спасибо за хороший новый синтаксис создания документа. 1.4 - хороший материал. – taber

Смежные вопросы