问题
I have a page where I need to have about 30 Facebook Like buttons. They all Like the same url. Basically just duplicate HTML code everywhere.
Anyways, when you load the page, every single Facebook Like Button div makes calls back and forth to Facebook. You can see it in the dev tools going back and forth. Slows down the page load a lot.
Is there a more efficient solution to this problem?
UPDATE
Let me ask an alternate question: Is there any way to dynamically connect each Facebook div like button to Facebook servers on demand? So basically, when the page loads, none of the Facebook div's make the connection to Facebook and a script is able to go through each button and (on demand) run the script that connects it. Is this possible? Right now, it appears that the way it works is that my page downloads the all.js
from Facebook. This script finds all facebook div's on the page and connects them to Facebook and makes them into Like buttons. If there was a way to run this script selectively on any div you wanted to, that would help me get closer to a solution...
回答1:
If there was a way to run this script selectively on any div you wanted to, that would help me get closer to a solution...
yes, you can run FB.XFBML.parse();
on a particular DOM object. So dynamically add the like button code to the div, then call FB.XFBML.parse();
on it. See: http://developers.facebook.com/docs/reference/javascript/FB.XFBML.parse/
FB.XFBML.parse(document.getElementById('foo'));
回答2:
I know this is an old topic but this may come in handy for others with the same problem.
If you have tons of facebook widgets for example one per result on a search results page and you want them all to render yet don't want to hit your user with tons of connections at the same time you can use this to throttle the rendering.
Code:
var fbThrottle = (function () {
var settings = {
// how many widgets can be rendering at any one time
simultaneousRenders: 3,
// how often to add a new widget to the queue, if the queue is not full
renderInterval: 100,
// max amount of time we will wait until marking a widget as rendered
// this is in place so as not to block the queue if a widget takes too long
maxRenderWaitFailsafe: 5000,
// how long to wait before calling the callback function (if supplied)
// after a widget finishes rendering. can be used to say set the area visible after render if you had it hidden to prevent fout.
callbackDelay: 250,
};
var fbWidgets = [];
var activeRenders = 0;
setInterval(function () {
if (fbWidgets.length == 0)
return;
if (!window.FB)
return;
if (activeRenders < settings.simultaneousRenders) {
var obj = fbWidgets.shift();
if (typeof obj !== 'undefined') {
activeRenders++;
(function () {
var currentRenderDone = false;
setTimeout(function () {
if (!currentRenderDone) {
activeRenders--;
currentRenderDone = true;
}
}, settings.maxRenderWaitFailsafe);
window.FB.XFBML.parse(obj.widget, function () {
if (!currentRenderDone) {
activeRenders--;
currentRenderDone = true;
}
if (typeof obj.callback === 'function') {
setTimeout(function () {
obj.callback();
}, settings.callbackDelay);
}
});
})();
}
}
}, settings.renderInterval);
return {
add: function (widget, callback, top) {
if (typeof widget === 'undefined')
return;
if (typeof widget === 'string')
widget = document.getElementById(widget);
var obj = {
widget: widget,
callback: callback
};
if (top)
fbWidgets.unshift(obj);
else {
fbWidgets.push(obj);
}
},
};
})();
Usage:
You can add the elements to the throttle all at once, or have sonar pass them in as they become visible.
// add in the element to be rendered to the end of the list
fbThrottle.add(element);
// or you can pass in just the id
fbThrottle.add("idOfElement");
// you can pass in a callback as well
fbThrottle.add(element, function(){
// do something after
});
// you can add an element to the top of the list by setting the third parameter to true
fbThrottle.add(element, callback, true);
As Jakobud mentioned it is best to turn off the fb js api's automatic rendering of the widgets by turning xfbml off in your FB.init
window.FB.init({
xfbml: false
});
回答3:
If you are using the iFrame like button, maybe the XFBML Like button wouldn't make those calls.
You'd have to incorporate the facebook jdk including the authentication script, which seems like a lot for a few like buttons. I would only try this if it is crucial to have many like buttons instead of just one.
回答4:
That's just bad design. Every like button will create its own iFrame, and there's nothing you can do about it.
回答5:
After much testing, this was my final solution:
Loading the Facebook all.js
SDK automatically parses all Facebook Like buttons on the page. There is unfortunately no option to load the SDK without parsing existing Facebook Like buttons.
Two solutions:
Load the SDK and not have any Facebook Like buttons on your page. Then, whenever there is a Like button that is visible on the screen, load in the Like button html/fbxml and then parse the markup using the SDK. I did not test this.
Don't load the SDK at all. Simply use AJAX to dynamically add a Facebook iframe in wherever you want to load one up. I went with this solution.
回答6:
You can use parameters to make your URL slightly different and set each Like a different ref attribute.
来源:https://stackoverflow.com/questions/9136254/html-how-to-efficiently-do-multiple-facebook-like-buttons-on-one-page