1

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

Community
  • 1
  • 1
Eric
  • 5,104
  • 10
  • 41
  • 70

3 Answers3

2

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.

Karl Anderson
  • 34,606
  • 12
  • 65
  • 80
  • That did not solve the problem. Now I have the Facebook library throwing an "Uncaught [object Object]" error. – Eric Aug 19 '13 at 00:51
  • 2
    The answer `$(this)` was in reference to your question about the error message "... has no method `attr`." – Karl Anderson Aug 19 '13 at 00:54
  • What is the `FB.XFBML.parse()` method expecting? – Karl Anderson Aug 19 '13 at 00:55
  • console.log('xfbml parsing .'+$(this).attr('class')+' and data-href '+$(this).attr('data-href')); – Daniel Aug 19 '13 at 00:55
  • Ah! Ok let me try it... that fixed the error. Thank you! Now my debug code looks right and is showing me the correct objects that I need Facebook to parse, but FB is simply not parsing them. Maybe it's how I'm passing the object on the FB.XFBML.parse() call? Facebook docs: "Alternately, to only evaluate a portion of a document, you can pass in a single element. `FB.XFBML.parse(document.getElementById('foo'));` – Eric Aug 19 '13 at 00:56
  • @Eric - do not change the `this` as the argument to the Facebook call, but rather only change `this` to `$(this)` when you want to use a jQuery method. See `Note:` in my answer. – Karl Anderson Aug 19 '13 at 00:59
  • Right. I still have `FB.XFBML.parse( this );` for the Facebook call. It seems like Facebook is just ignoring it. – Eric Aug 19 '13 at 01:00
  • @Eric - sounds like a new question to me. – Karl Anderson Aug 19 '13 at 01:01
  • @Eric - if you feel my answer helped you, then feel free to up-vote and/or accept the answer. – Karl Anderson Aug 19 '13 at 01:05
  • Post was you are logging from the loop. – Daniel Aug 19 '13 at 01:05
  • New question posted about why it's not working... http://stackoverflow.com/questions/18305251/fb-xfbml-parse-on-individual-element-does-nothing – Eric Aug 19 '13 at 01:20
1
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.

Daniel
  • 579
  • 2
  • 7
  • 1
    Alternately, to only evaluate a portion of a document, you can pass in a single element. FB.XFBML.parse(document.getElementById('foo')); So it is expecting a DOM node, not a jQuery object. – Daniel Aug 19 '13 at 00:58
  • Got it. So how can I get the DOM node from the jQuery object returned by jQuery's each() method? – Eric Aug 19 '13 at 00:59
  • this is the raw node. $(this) takes that node and wraps it in jQuery. – Daniel Aug 19 '13 at 01:00
  • My code says `FB.XFBML.parse( this );` so I'm giving Facebook the DOM node that it requires, yes? – Eric Aug 19 '13 at 01:01
  • Hmmm but it's still not working. So I guess the problem might be in Facebook's library. Any ideas on how to fix that? – Eric Aug 19 '13 at 01:13
  • Added a new question: http://stackoverflow.com/questions/18305251/fb-xfbml-parse-on-individual-element-does-nothing – Eric Aug 19 '13 at 01:19
1

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'));
});
Tushar Gupta - curioustushar
  • 58,085
  • 24
  • 103
  • 107