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 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>
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). 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 FB's parse method say:
...to only evaluate a portion of a document, you can pass in a single element.
FB.XFBML.parse(document.getElementById('foo'));
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 it doesn't work. The code seems to be passing the elements to Facebook after they're loaded, but they aren't parsing. Code:
// "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 & append
newDivName = "d"+String(new Date().valueOf());
var $newHtml = $("<div id='"+newDivName+"'>"+html+"</div>");
c.append($newHtml);
// walk through new HTML and get all Facebook "like" buttons and parse them
$('#'+newDivName+' .fb-like').each(function() {
FB.XFBML.parse(this);
});
}
}
});
});
There's no error message, it just doesn't produce any results. The debug code to the console looks perfect, it's finding all the right elements.
UPDATE play with it at this simple jsfiddle: http://jsfiddle.net/pnoeric/NF2jz/4372/
UPDATE 2 I also tried changing the code from HTML5 to FBML (click "Get Code" on this page to see the difference), which not only had the same result but now also would only load one additional button on the ajax call, instead of two. So it got worse! You can play with the FBML version here: http://jsfiddle.net/pnoeric/4QkbX/2/
The docs specifies that the dom element should be root DOM node, defaults to body
. So I replace.each
function call with a single call to a .parse
method with the created DOM element. Here is a jsfiddle.
FB.XFBML.parse($newhtml[0]);
Note: FB.XFBML.parse() should be called on a parent element of the widget, not directly on the XFBML element itself.
In my case the accepted solution wouldn't work, because the FB posts are appended in the same DOM container.
What i ended up doing, is run a FB.XFBML.parse() to the container, use an .each loop and removeClass the fb-post, add class facebook-post-loaded. Then on subsequent Ajax calls and fetches of new fb posts, the FB.XFBML.parse() would not pick the already loaded elements since they don't have the fb-post class anymore.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With