Использование document.createDocumentFragment () дочерних элементов dom, которые содержат jQuery.data - PullRequest
2 голосов
/ 11 мая 2010

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

Вот мой код:


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. Иногда есть тонны строк, поэтому я хочу, чтобы все было оптимизировано с точки зрения скорости.

Спасибо!

Ответы [ 2 ]

1 голос
/ 12 мая 2010

Извините, я не совсем ясно: я хочу выиграть в производительности от использования 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. Он выглядит как .get (0) и возвращает данные без изменений!

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

1 голос
/ 11 мая 2010

Вы запускаете 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'));

Дайте мне знать, если это работает.

РЕДАКТИРОВАТЬ: изменил мою ошибку с innerHTML

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...