HTML - How to efficiently do multiple Facebook Like buttons on one page

六眼飞鱼酱① 提交于 2019-12-08 08:45:31

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'));

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

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.

That's just bad design. Every like button will create its own iFrame, and there's nothing you can do about it.

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:

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

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

You can use parameters to make your URL slightly different and set each Like a different ref attribute.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!