Reputation: 6752
I'm using Facebook's "Page Plugin" widget. On Facebook's page, it is written:
If you want to adjust the plugin's width on window resize, you manually need to rerender the plugin.
How can I dynamically change this plugin's width without page refreshing (with, for example, Firefox responsive view - CTRL+M shortcut).
And yeah, I have read THIS post, but none of these solutions tells how to rerender the plugin.
Upvotes: 9
Views: 18858
Reputation: 635
I know this has already been answered, but I've been struggling with this for a couple days now and came up with my own solution that I wanted to post to help others. For my use case, I needed to adjust both the width and the height based on the screen size. Therefore, my solution dynamically resizes both width AND height.
To start, I calculate the width and height of the container holding the facebook plugin on page load (code shown later in this post). I then use JS to write in the element. I do not write the actual HTML code for facebook plugin itself (the div with the fb-page class with a following blockquote). My initial HTML code looks like this:
<div id="fb-root"></div>
<script async defer crossorigin="anonymous" src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v19.0" nonce="jkIFp94z"></script>
<div class="fb-superimpose">
<img class="news-image" src="img/bunny.png" alt="">
<div id="fbPageContainer" class="fb-plugin">
</div>
</div>
I do realize you can set data-adapt-container-width="true", and it will take care of sizing the width appropriately on page load. However, this doesn't size the height as needed.
Also, if you set data-adapt-container-width="true", I experienced issues with resizing. Specifically, if I shrunk the window, my JS could resize the plugin correctly by updating the width and height attributes and calling FB.XFBML.parse(). However, when I began to increase the size of the window again, the plugin did not adapt to the increased size (despite my JS dynamically updating the data-width and data-height). Once I set data-adapt-container-width="false", it began working. See this post: https://stackoverflow.com/a/55699127/7531768 .
This is more a problem if you are using JS to dynamically update the height attribute. If you are only needing to update the width attribute, your best bet is probably to set the data-adapt-container-width attribute to true, then simply use FB.XFBML.parse() to update the plugin on window resize. You would not need to use $().attr to update the width. In this case, you would use CSS to size the container as you wish and let data-adapt-container-width handle it through FB.XFBML.parse().
Here is my JS code, tweaked from https://stackoverflow.com/a/55894579/7531768 and https://stackoverflow.com/a/30837877/7531768 :
$(document).ready(function() {
var container_width = Number($('.fb-plugin').width()).toFixed(0);
var container_height = Number($('.fb-superimpose').height()).toFixed(0)-5;
$('#fbPageContainer').html('<div id="divFacebookFeed" class="fb-page bebebop" data-href="https://www.facebook.com/" data-tabs="timeline" data-width="' + container_width + '" data-height="' + container_height + '" data-small-header="true" data-adapt-container-width="false" data-hide-cover="false" data-show-facepile="true" data-show-posts="true"><blockquote cite="https://www.facebook.com/" class="fb-xfbml-parse-ignore"><a href="https://www.facebook.com/">Mytestpage</a></blockquote></div>');
});
var FB_UPDATE_TIMEOUT = null;
resize = () => {
if(FB_UPDATE_TIMEOUT === null) {
FB_UPDATE_TIMEOUT = window.setTimeout(function() {
FB_UPDATE_TIMEOUT = null;
var container_width = Number($('.fb-plugin').width()).toFixed(0);
var container_height = Number($('.fb-superimpose').height()).toFixed(0)-5;
if (!isNaN(container_width)) {
$(".fb-page").attr("data-width", container_width);
}
if (!isNaN(container_height)){
$(".fb-page").attr("data-height", container_height);
}
if (typeof FB !== 'undefined') {
FB.XFBML.parse();
}
}, 1000);
}
};
window.addEventListener('resize', this.resize);
I'm sure it can be optimized and cleaned up a bit better, but essentially it writes out the HTML code on page load. This guarantees the plugin is loaded with the correct width and height. Technically, you could just write in the HTML code (as opposed to having JS write it), and then call resize() to update it. The problem I have with this is that it will load the plugin and then reload it. Effectively, this is loading it twice!
So that's page load, now for resizing the window. For this, I simply update the data-width and data-height attributes based on the container that holds it, then run FB.XFBML.parse(). I saw a ton of answers mentioning this approach, but a lot of them didn't include the timeout. This is important, because otherwise you are going to run the function multiple times during resize and facebook could end up blocking the requests.
Finally, not that it is necessarily pertinent, here is my css code:
.fb-superimpose {
position: relative;
display: inline-block;
width: 100%;
}
.news-image {
margin-left: 10%;
width: 50%;
height: auto;
}
.fb-plugin {
position: absolute;
top: 0%;
left: 39.5%;
width: 60.5%;
}
Hopefully this helps someone else avoid the struggles I had. Happy coding!
Upvotes: 0
Reputation: 700
A couple of small improvements to jroi_web's good work.
<div id="myFBContainer"></div>
<script>
function renderFB() {
var container = document.getElementById('myFBContainer');
if (window.getComputedStyle(container).display !== 'none') {
var width = container.offsetWidth;
const fbHTML = '<div class="fb-page" data-href="https://www.facebook.com/facebook" data-tabs="timeline" data-width="' + width + '" data-height="" data-small-header="true" data-adapt-container-width="true" data-hide-cover="true" data-show-facepile="false" > <blockquote cite="https://www.facebook.com/facebook" class="fb-xfbml-parse-ignore" > <a href="https://www.facebook.com/facebook">Facebook</a> </blockquote> </div>';
container.innerHTML = fbHTML;
FB.XFBML.parse();
}
}
window.addEventListener('resize', renderFB);
document.addEventListener('DOMContentLoaded', renderFB);
</script>
Upvotes: 0
Reputation: 1764
Yep, facebook page plugin (and other their plugins) renders only on page load. And if this plugin is hided (or window after rendering was resized) you need to tell FB rerender his plugins. This works perfectly with calling FB.XFBML.parse() after showing/resizing.
You can do it like this:
in HTML:
<div class="fb-page" data-href="{url}" data-hide-cover="false" data-show-facepile="true" data-show-posts="false"><div class="fb-xfbml-parse-ignore"><blockquote cite="{url}"><a href="{url}">{title}</a></blockquote></div></div>
in Javascript:
function changeFBPagePlugin(width, height, url) {
if (!isNaN(width) && !isNaN(height)) {
$(".fb-page").attr("data-width", width).attr("data-height", height);
}
if (url) {
$(".fb-page").attr("data-href", url);
}
FB.XFBML.parse();
}
Just call for rerendering (if you want show plugin after hiding)
changeFBPagePlugin(355, 244);
or
changeFBPagePlugin(355, 244, "https://facebook.com/PageNameHere");
if you want to change other FB page plugin
Upvotes: 6
Reputation: 81
Using code from the above answers, the below code works for me:
<div id="fb-root"></div>
<!--
From https://developers.facebook.com/docs/plugins/page-plugin/
-->
<div id="Facebook-Widget">
<div class="fb-page" data-href="{url}" data-tabs="timeline"
data-small-header="false" data-adapt-container-width="true"
data-hide-cover="false" data-show-facepile="true">
<blockquote cite="{url}" class="fb-xfbml-parse-ignore"><a
href="{url}">{title}</a></blockquote>
</div>
</div>
<script type="text/javascript">
var Example =
{
foFuncTimeOut: null,
//----------------------------------------------------------------------------------------------------
initializeRoutines: function ()
{
// Facebook sidebar
// From https://developers.facebook.com/docs/plugins/page-plugin/
(function (d, s, id)
{
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id))
{
return;
}
js = d.createElement(s);
js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.10";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
},
// -------------------------------------------------------------------------------------------------------------------
setupFacebook: function ()
{
var loWidget = jQuery('#Facebook-Widget');
if (loWidget.length == 0)
{
return;
}
Example.resizeFacebook(loWidget);
jQuery(window).resize(function ()
{
Example.resizeFacebook(loWidget);
});
},
// -------------------------------------------------------------------------------------------------------------------
// From http://stackoverflow.com/questions/30083986/facebook-page-plugin-rerender-change-width-dynamically-responsive-rwd
resizeFacebook: function (toWidget)
{
if (Routines.foFuncTimeOut != null)
{
clearTimeout(Routines.foFuncTimeOut);
}
Routines.foFuncTimeOut = setTimeout(function ()
{
// Query the block above the Facebook widget.
var lnWidth = jQuery('#block-views-block-blog-management-blog-listing-block').width();
if (lnWidth < 180)
{
lnWidth = 180;
}
if (lnWidth > 500)
{
lnWidth = 500;
}
var lnHeight = (jQuery(window).width() >= 768) ? 1200 : 700;
toWidget.css('width', lnWidth + 'px');
toWidget.css('height', lnHeight + 'px');
var loFB = toWidget.find('.fb-page');
loFB.css('width', lnWidth + 'px');
loFB.css('height', lnHeight + 'px');
// data-width & data-height only accept whole numbers.
loFB.attr('data-width', Math.floor(lnWidth));
loFB.attr('data-height', Math.floor(lnHeight));
if (typeof FB !== 'undefined')
{
FB.XFBML.parse();
}
}, 1000);
},
//----------------------------------------------------------------------------------------------------
};
Example.initializeRoutines();
Example.setupFacebook();
</script>
Upvotes: 0
Reputation: 221
A solution for this problem is:
(function($){
var a = null;
$(window).resize(function(){
if(a != null) {
clearTimeout(a);
}
a = setTimeout(function(){
FB.XFBML.parse();
},1000)
})
})(jQuery)
Upvotes: 12
Reputation: 420
Solution is :
FB.XFBML.parse();
Solved my problems with all hidden facebook plugins after appending "hidden" div's contents into a main div, using the menu from the jsfiddle above .
Menu appending content from hidden divs into a main div
I was going use another menu, thats what i was going to do .
I used FB.XFBML.parse();
in my the funcion, before the return false;
and it worked perfectly for page, comments, likes, all plugins are now parsed every time the menu is clicked .
Thank you .
Upvotes: 3
Reputation: 1984
For JavaScript/jQuery approach, you may want to listen to on window resize event and reload the Facebook Page Plugin Div container. Make sure that the FB Page plugin is wrapped around a parent div so we can use its size when we reload the div.
<div id="pageContainer">
<div class="fb-page" data-href="https://www.facebook.com/facebook" data-width="500" data-height="250" data-small-header="false" data-adapt-container-width="true" data-hide-cover="false" data-show-facepile="true" data-show-posts="true"><div class="fb-xfbml-parse-ignore"><blockquote cite="https://www.facebook.com/facebook"><a href="https://www.facebook.com/facebook">Facebook</a></blockquote></div></div>
</div>
$( window ).resize(function() {
var container_width = $('#pageContainer').width();
$('#pageContainer').html('<div class="fb-page" data-href="https://www.facebook.com/facebook" data-width="' + container_width + '" data-height="250" data-small-header="false" data-adapt-container-width="true" data-hide-cover="false" data-show-facepile="true" data-show-posts="true"><div class="fb-xfbml-parse-ignore"><blockquote cite="https://www.facebook.com/facebook"><a href="https://www.facebook.com/facebook">Facebook</a></blockquote></div></div>');
FB.XFBML.parse();
});
Upvotes: 20