How to resize Facebook Canvas (iFrame) app correctly?

I need to adjust the size of the canvas after updating the contents of the page. I can do it explicitly

FB.Canvas.setSize({ width: 760, height: 1480 }); 

however, it does not work without parameters, i.e. .setSize() .

In addition, I can adjust the height to

 FB.Canvas.setAutoResize(true); 

but only increasing - it does not reduce the height while reducing the content.

The following lines do not work:

 FB.Arbiter.inform("setSize", FB.Canvas._computeContentSize()); FB.Canvas.setSize(FB.Canvas._computeContentSize()); 

How to make it work?

A few more comments on the topic:

on this topic:

How do you control the size of your Canvas Facebook apps?

+7
source share
10 answers

Do not record your own function for automatic resizing. Fb has one:

 FB.Canvas.setAutoResize(); 

If you know when you need to resize, use

 FB.Canvas.setSize() 

So, if you want to do less when you click a link, paste it into a function, and then call that function later:

 function sizeChangeCallback() { FB.Canvas.setSize(); } //start some function or on click event - here i used jquery $("#something").click(function() { sizeChangeCallback() }); 

You do not need to set an explicit height, but sometimes you may have problems with dynamic xfbml elements, such as a comment plugin. Try using the event subscription callback:

  FB.Event.subscribe('xfbml.render', function(response) { FB.Canvas.setAutoResize(); }); 

http://developers.facebook.com/docs/reference/javascript/FB.Canvas.setSize/

http://developers.facebook.com/docs/reference/javascript/FB.Canvas.setAutoResize/

http://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/

+7
source

I managed to make the .setSize() work by delaying its execution (as suggested in various forums):

 window.setTimeout(function() { FB.Canvas.setSize(); }, 250); 

If you have XFBLM elements, especially fb:comments , then you need to analyze the page before setting its size

 window.setTimeout(function() { FB.XFBML.parse(); FB.Canvas.setSize(); }, 250); 

Please note that you need to run this script after your content block, otherwise increase the time interval (in ms), allowing the web server and browser browser to create content before changing the canvas size.

This approach only increases the height of your page and does not reduce it. You can achieve the reduction manually by executing the following line before the code above

 FB.Canvas.setSize({height: 480}); // min height - .setSize() won't reduce it 

however, there is a drawback - the page will blink due to double resizing.

In addition, it is proposed to run .setSize at several time intervals to account for delayed content:

 FB.Array.forEach([300, 600, 1000, 2000], function(delay) { setTimeout(function() { FB.XFBML.parse(); FB.Canvas.setSize(); }, delay) }); 

In this case, the page and XFBML elements become quite blinking.

+3
source

We have pages in our iframe that add content to the page and then allow the user to update the content on the page. In these cases, we saw the same where the content was not reduced when it was necessary.

FB.Canvas.setSize () calls _computeContentSize, which is shown below:

 _computeContentSize: function() { var body = document.body, docElement = document.documentElement, right = 0, bottom = Math.max( Math.max(body.offsetHeight, body.scrollHeight) + body.offsetTop, Math.max(docElement.offsetHeight, docElement.scrollHeight) + docElement.offsetTop); if (body.offsetWidth < body.scrollWidth) { right = body.scrollWidth + body.offsetLeft; } else { FB.Array.forEach(body.childNodes, function(child) { var childRight = child.offsetWidth + child.offsetLeft; if (childRight > right) { right = childRight; } }); } if (docElement.clientLeft > 0) { right += (docElement.clientLeft * 2); } if (docElement.clientTop > 0) { bottom += (docElement.clientTop * 2); } return {height: bottom, width: right}; }, 

The problem line is here:

 bottom = Math.max( Math.max(body.offsetHeight, body.scrollHeight) + body.offsetTop, Math.max(docElement.offsetHeight, docElement.scrollHeight) + docElement.offsetTop); 

Even if the content inside your iframe has decreased, the value of body.offsetHeight will not decrease.

To solve this problem, we created a custom version of the computeContentSize function, which only processes docElement for height, for example:

 function rfComputeContentSize() { var body = document.body, docElement = document.documentElement, right = 0, bottom = Math.max(docElement.offsetHeight, docElement.scrollHeight) + docElement.offsetTop; if (body.offsetWidth < body.scrollWidth) { right = body.scrollWidth + body.offsetLeft; } else { FB.Array.forEach(body.childNodes, function(child) { var childRight = child.offsetWidth + child.offsetLeft; if (childRight > right) { right = childRight; } }); } if (docElement.clientLeft > 0) { right += (docElement.clientLeft * 2); } if (docElement.clientTop > 0) { bottom += (docElement.clientTop * 2); } return {height: bottom, width: right}; } 

At any time, when we want to resize and know that the content can be compressed, we will use a user-defined function to transfer the content to setSize (for example, FB.Canvas.setSize (rfComputeContentSize ())), and at any time we know that content will be only, we will use the standard function FB.Canvas.setSize ().

Please note that we used setAutoGrow (), and I did not check, but I assume that it uses the same function to determine the size. We have disabled our call to setAutoGrow () and will need to be vigilant about calling setSize () at the appropriate time.

Facebook bug recorded: https://developers.facebook.com/bugs/228704057203827

+2
source

We ran into a problem when their FB.Canvas functions FB.Canvas not work, although everything was correctly initialized because theyre using an 'IFRAME instead of an iframe in their cross-domain JS setup, hence there is no XHTML compatibility.

We fixed this by prototyping our own createElement function and overriding them. Just put this right after enabling Facebooks all.js:

 document.__createElement = document.createElement; document.createElement = function(tagName) { return document.__createElement(tagName.toLowerCase()); } 
+1
source

a bit of redundant functionality, but this article explains why you cannot do it dynamically and provides the simplest solution ... http://www.twistermc.com/36764/shrink-facebook-tabs/ The answer is simple: Compression is really small and then after a pause use AutoGrow to make it the right size ... Alice in Wonderland.

  • I say simpler, because from the point of view of the developer and the user, this slows down by about 1/4 of a second, and the user gets a tiny flash of scroll bars ...
+1
source

Bobby's answer is very good. The only thing I would like to add to this is that some people managed to achieve page compression by doing the following:

FB.Canvas.setSize({ width: 760, height: 10 });

And then follow it:

FB.Canvas.setAutoResize();

You do not need to use 10, just something smaller than the minimum size of your page. Then FB.Canvas.setAutoResize() should go ahead and create the correct height again and continue updating. The only time you need to call FB.Canvas.setSize({ width: 760, height: 10 }); again, it would be if the contents were compressed again.

The danger of this is that if FB.Canvas.setAutoResize(); does not work, you can disable the content.

0
source

None of this worked for me. Be sure to enter this before the closing tag.

 <div id="fb-root"></div> <script type="text/javascript"> window.fbAsyncInit = function() { //Der folgende Code ändert die Grösse des iFrames alle 100ms FB.Canvas.setAutoResize(100); }; (function() { var e = document.createElement('script'); e.async = true; e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js'; document.getElementById('fb-root').appendChild(e); }()); </script> 
0
source

I tried using FB.Canvas.setSize(e); to resize my application, but it did not change at all.

I looked in JavaScript Javascript and found out that FB.Canvas.setSize calls the function FB.Arbiter.inform('setSize',e) .

If I call the function FB.Arbiter.inform('setSize',{ width: 760, height: 1480 }) directly from my code, the canvas size changes correctly.

0
source

This worked for me:

 <script type='text/javascript'> window.onload=function() { FB.Canvas.setSize({width:760,height:document.body.offsetHeight}); } </script> 

Please note that you do not need FB.init if you are not using it for other reasons.

0
source

When resizing to a minimum height, be sure to make it a little larger than it is to take into account the horizontal scroll bar and some additional pixels that some browsers add, otherwise you will get vertical scrolling.

Also, I do not recommend using body to calculate height.

This worked for me:

 window.fbAsyncInit = function() {FB.Canvas.setSize({height:document.getElementById('m_table').offsetHeight+40});} 

where m_table is the id of the table with all my content (you can use a div instead).

0
source

All Articles