Reputation: 2082
I'm very new to making jQuery plugins and there is one problem i stumble upon every time. The plugin below is a simple plugin to embed a facebook likebox for a page or link to a user profile based on a username or facebook url. It works like a charm when it's executed once.
When executed multiple times only the last one gets filled with the $.ajax part. If i console.log($this) there al the last one.
It looks like the $this in the ajax call is overwritten... it also happens in other plugins when i use another each() in the plugin.
I hope i'm clear, i tried to put it in a jsFiddle but i get the error "Input plain JavaScript code, no HTML."
jQuery.fn.facebookEmbed = function( options ) {
var defaults = {
likebox: "Loading facebook...",
faces: false,
stream: true,
header: false,
width: 252,
customClass: 'facebookembed',
account: "skrillex"
};
var settings = $.extend( {}, defaults, options );
if(!$('#fb-root').length) { $('body').prepend('<div id="fb-root"></div><script src="http://connect.facebook.net/en_US/all.js#xfbml=1"></script>'); }
return this.each(function() {
$this = $(this);
$this.addClass(settings.customClass);
if(settings.loading) { $(this).html('<span class="facebook-loading">'+settings.loading+'</span>'); }
var url = ($this.attr('data-account')) ? $this.attr('data-account') : settings.account;
if(!/facebook.com/.test(url)) {
url = "http://www.facebook.com/"+url;
}
var user = (/pages/.test(url)) ? url.split("/").pop() : url.match(/https?:\/\/(www\.)?facebook\.com\/(#!\/)?@?([^\/]*)/)[3];
// here begins the trouble, i think
$.ajax( {
url: 'http://graph.facebook.com/'+user
, dataType: 'json'
, success: function( data ) {
if(data.category) {
// I guess $this is overwritten somehow?
$this.html('<div class="facebookembed"><fb:like-box href="'+url+'" width="'+settings.width+'" show_faces="'+settings.faces+'" stream="'+settings.stream+'" header="'+settings.header+'"></fb:like-box></div>');
} else {
$this.html('<div class="facebookuser"><a href="'+url+'" target="_blank"><img src="http://graph.facebook.com/'+user+'/picture" /> Wordt vrienden met <strong>'+data.name+'</strong> op Facebook</a>');
}
}
, error: function( data ) { $this.text('Deze gebruiker bestaat niet of niet meer...'); }
} );
});
};
Html:
<div class="facebook-feed" data-account="skrillex"></div>
<div class="facebook-feed" data-account="noisia"></div>
etc..
<script type="text/javascript">$('.facebook-feed').facebookEmbed();</script>
Upvotes: 2
Views: 175
Reputation: 20377
Without testing it looks like you are using $this
in global scope. To keep it in local scope add var
into declaration:
var $this = $(this);
Upvotes: 4
Reputation: 17550
Have you tried the context
option?
$.ajax( {
url: 'http://graph.facebook.com/'+user
, context: $this
, ...
From the documentation:
This object will be made the context of all Ajax-related callbacks. By default, the context is an object that represents the ajax settings used in the call ($.ajaxSettings merged with the settings passed to $.ajax).
In your code you set the $this
variable to a new object before the ajax call returns. Presumely all ajax calls return after you have set $this
in the last each
method.
Upvotes: 0