Как использовать jQuery each() для анализа загруженных элементов

У меня есть большая страница с кнопкой «загрузить еще» внизу; каждый щелчок по «загрузить больше» загружает больше контента через AJAX. Частью этого контента являются кнопки лайков и комментариев Facebook:

<div class="fb-like" data-href="http://mysite.com/a<?=$x ?>" data-width="100" data-layout="button_count" data-show-faces="false" data-send="false"></div>
<div class="fb-comments" data-href="http://mysite.com/a<?=$x ?>" data-width="435"></div>

После загрузки дополнительного контента я могу попросить Facebook повторно проанализировать всю страницу с помощью FB.XFBML.parse(); (что приводит к тому, что эти элементы div превращаются в настоящие кнопки «Нравится» и формы комментариев). Это работает отлично, однако сразу становится медленным, поскольку Facebook повторно анализирует контент, который уже был на странице, а не только новый контент. Каждый раз, когда пользователь нажимает «загрузить еще», он анализирует всю страницу, поэтому функция FB делает все больше и больше.

А теперь хорошие новости: документы для синтаксического анализа FB говорят, что вы можете попросить Facebook проанализировать только один элемент. Итак, я подумал: ладно, когда пользователь нажмет «загрузить еще», я оберну этот свежий HTML в уникальный div, затем использую jQuery, чтобы просмотреть div, найти все теги Facebook и попросить Facebook проанализировать только их. Хорошая идея, верно? Но я не могу заставить его работать. :-)

Итак, вот код, который должен помочь:

// "c" is my container div (a jQuery object, i.e. c = $('#container'); ) 
// "load more" button
$('#loadmore').click(function() {
    $.ajax({
        url: "/loadmore.php",
        success: function(html) {
            if(html) {
                // wrap new HTML in special div
                newDivName = "d"+String(new Date().valueOf());
                var $newHtml = $("<div id='"+newDivName+"'>"+html+"</div>");

                // append it to existing content, and tell Isotope
                c.append($newHtml);
                if(c.hasClass('isotope-loaded')) { c.isotope( 'appended', $newHtml ); }

                // walk through new HTML and get all Facebook "like" buttons and parse them
                $('#'+newDivName+' .fb-like').each(function() {
                    console.log('xfbml parsing .'+this.attr('class')+' and data-href '+this.attr('data-href'));
                    FB.XFBML.parse(this);
                });
            }
        }
    });

});

Но я получаю: Uncaught TypeError: Object #<HTMLDivElement> has no method 'attr' (что говорит мне, что мой each() работает неправильно)... почему?

ОБНОВЛЕНИЕ: ответ найден ниже, чтобы решить эту проблему, но он все еще не работает. См. новый вопрос: FB.XFBML.parse() для отдельного элемента делает ничего


person Eric    schedule 19.08.2013    source источник


Ответы (3)


console.log('xfbml parsing .'+$(this).attr('class')+' and data-href '+$(this).attr('data-href'));

Вам все еще нужно передать этот объект в facebook. attr — это метод jQuery.

person Daniel    schedule 19.08.2013
comment
В качестве альтернативы, чтобы оценить только часть документа, вы можете передать один элемент. FB.XFBML.parse(document.getElementById('foo')); Таким образом, ожидается узел DOM, а не объект jQuery. - person Daniel; 19.08.2013
comment
Понятно. Итак, как я могу получить узел DOM из объекта jQuery, возвращаемого методом jQuery each()? - person Eric; 19.08.2013
comment
это необработанный узел. $(this) берет этот узел и оборачивает его в jQuery. - person Daniel; 19.08.2013
comment
В моем коде указано FB.XFBML.parse( this );, поэтому я даю Facebook требуемый DOM-узел, да? - person Eric; 19.08.2013
comment
Хм, но он все еще не работает. Так что я предполагаю, что проблема может быть в библиотеке Facebook. Любые идеи о том, как это исправить? - person Eric; 19.08.2013
comment
Добавлен новый вопрос: stackoverflow.com/questions/18305251/ - person Eric; 19.08.2013

Используйте $(this) вместо this.

Примечание. $(this) делает элемент, возвращаемый методом .each(), снова обернутым объектом набора jQuery, и вы можете снова выполнять с ним действия jQuery; в противном случае this является необработанным значением.

person Karl Anderson    schedule 19.08.2013
comment
Это не решило проблему. Теперь у меня есть библиотека Facebook, выдающая ошибку Uncaught [object Object]. - person Eric; 19.08.2013
comment
Ответ $(this) был связан с вашим вопросом о сообщении об ошибке... нет метода attr. - person Karl Anderson; 19.08.2013
comment
Что ожидает метод FB.XFBML.parse()? - person Karl Anderson; 19.08.2013
comment
console.log('Разбор xfbml .'+$(this).attr('class')+' and data-href '+$(this).attr('data-href')); - person Daniel; 19.08.2013
comment
Ах! Хорошо, позвольте мне попробовать... это исправило ошибку. Спасибо! Теперь мой код отладки выглядит правильно и показывает мне правильные объекты, которые мне нужны для анализа Facebook, но FB просто не анализирует их. Может быть, это то, как я передаю объект при вызове FB.XFBML.parse()? Документы Facebook: в качестве альтернативы, чтобы оценить только часть документа, вы можете передать один элемент. FB.XFBML.parse(document.getElementById('foo')); - person Eric; 19.08.2013
comment
@Eric - не меняйте this в качестве аргумента вызова Facebook, а измените только this на $(this), когда вы хотите использовать метод jQuery. См. Note: в моем ответе. - person Karl Anderson; 19.08.2013
comment
Верно. У меня еще есть FB.XFBML.parse( this ); для звонка в Facebook. Похоже, что Facebook просто игнорирует это. - person Eric; 19.08.2013
comment
@ Эрик - звучит как новый вопрос для меня. - person Karl Anderson; 19.08.2013
comment
@ Эрик - если вы чувствуете, что мой ответ помог вам, не стесняйтесь голосовать и / или принимать ответ. - person Karl Anderson; 19.08.2013
comment
Сообщение было вы регистрируетесь из цикла. - person Daniel; 19.08.2013
comment
Опубликован новый вопрос о том, почему он не работает... для отдельного элемента ничего не делает"> stackoverflow.com/questions/18305251/ - person Eric; 19.08.2013

ДЕМО

.each() для перебора всех элементов с классом fb-like

$(this) относится к текущему элементу.

$(this).data('href')) получить значение data-href

используйте $(this).data('href')) вместо $(this).attr('data-href')

Рекомендуется и является хорошей практикой использовать data attribute вот так $(this).data('href'))

$('.fb-like').each(function () {
    console.log('xfbml parsing .' + $(this).attr('class') + ' and data-href ' + $(this).data('href'));
});
person Tushar Gupta - curioustushar    schedule 19.08.2013
comment
Отличное замечание по поводу функции data() - я действительно забыл об этом. Спасибо! - person Eric; 20.08.2013