Question

I have a big page with a "load more" button at the bottom; each click on "load more" loads more content via AJAX. Part of that content is Facebook like and comment buttons:

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

After loading the additional content, I can ask Facebook to re-parse the entire page with FB.XFBML.parse(); (which causes those divs to turn into actual like buttons and comment forms). This works perfectly, however, it gets slow right away, since Facebook re-parses the content that was already on the page, not just the new content. Every time the user clicks "load more" it parses the entire page, so there's just more and more for the FB function to do.

Now here's the good news: the docs for the FB parse say you can ask Facebook to parse just one element. So I thought, okay, when the user clicks "load more," I'll wrap that fresh HTML in a unique div, then use jQuery to walk through the div, find all the Facebook tags and ask Facebook to parse just those. Good idea, right? But I can't make it work. :-)

So here's the code that is supposed to do the trick:

// "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);
                });
            }
        }
    });

});

But I'm getting: Uncaught TypeError: Object #<HTMLDivElement> has no method 'attr' (which tells me my each() isn't working right)... why?

UPDATE: answer found below to solve this problem, but it's still not working. Please see new question: FB.XFBML.parse() on individual element does nothing

Was it helpful?

Solution 2

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

You still need to pass the raw this object to facebook. attr is a jQuery method.

OTHER TIPS

Use $(this) instead of just this.

Note: $(this) makes the item returned from the .each() method a jQuery wrapped set object again and let's you do jQuery things to it again; otherwise this is the raw value.

DEMO

.each() to loop through all elements with class fb-like

$(this) refers to the current element.

$(this).data('href')) get's the value of data-href

make use of $(this).data('href')) instead of $(this).attr('data-href')

It's advisable and good practice to use data attribute like this $(this).data('href'))

$('.fb-like').each(function () {
    console.log('xfbml parsing .' + $(this).attr('class') + ' and data-href ' + $(this).data('href'));
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top