Javascript 如何正确调整 Facebook Canvas 应用程序 (iFrame) 的大小?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4695918/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to resize Facebook Canvas app (iFrame) correctly?
提问by Andrei
I need to adjust canvas size after updating content of a page. I can do it explicitly by
更新页面内容后,我需要调整画布大小。我可以通过
FB.Canvas.setSize({ width: 760, height: 1480 });
however, it doesn't work without parameters, i.e. .setSize()
.
但是,它在没有参数的情况下不起作用,即.setSize()
.
Also, I can adjust the height by
另外,我可以通过以下方式调整高度
FB.Canvas.setAutoResize(true);
but only increasing - it doesn't reduce the height when content is reduced.
但只会增加 - 当内容减少时,它不会降低高度。
The following lines do not work:
以下几行不起作用:
FB.Arbiter.inform("setSize", FB.Canvas._computeContentSize());
FB.Canvas.setSize(FB.Canvas._computeContentSize());
How can one make it working?
怎样才能让它发挥作用?
Some more comments on the subject:
关于该主题的更多评论:
- http://developers.facebook.com/blog/post/93
- http://developers.facebook.com/docs/reference/javascript/fb.canvas.setautoresize
- http://developers.facebook.com/blog/post/93
- http://developers.facebook.com/docs/reference/javascript/fb.canvas.setautoresize
Related:
有关的:
- facebook-api: what's Facebook Connect cross-domain receiver URL?
- facebook-app: how can i change the height of a resizeable iframe application?
- Document height grows on resize when setting canvas dimensions dynamically
- facebook-api:什么是 Facebook Connect 跨域接收器 URL?
- facebook-app:如何更改可调整大小的 iframe 应用程序的高度?
- 动态设置画布尺寸时,文档高度会随着调整大小而增长
How do you control the size of your Facebook Canvas apps?
您如何控制 Facebook Canvas 应用程序的大小?
回答by Bob
Don't write your own function for timed Auto-resize. Fb has one:
不要为定时自动调整大小编写自己的函数。脸书有一个:
FB.Canvas.setAutoResize();
If you know when you need to resize it use
如果您知道什么时候需要调整它的大小,请使用
FB.Canvas.setSize()
So, if you want to make is smaller when you click a link, stick it in a function and then call that function later like:
因此,如果您想在单击链接时变小,请将其粘贴在一个函数中,然后稍后调用该函数,例如:
function sizeChangeCallback() {
FB.Canvas.setSize();
}
//start some function or on click event - here i used jquery
$("#something").click(function() {
sizeChangeCallback()
});
You don't need to set an explicit height, but sometimes you can have trouble with dynamic xfbml elements like the comments plugin. Try using an event subscribe callback:
您不需要设置明确的高度,但有时您可能会遇到动态 xfbml 元素(如注释插件)的问题。尝试使用事件订阅回调:
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.setSize/
http://developers.facebook.com/docs/reference/javascript/FB.Canvas.setAutoResize/
http://developers.facebook.com/docs/reference/javascript/FB.Canvas.setAutoResize/
http://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/
http://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/
回答by Andrei
I have managed to make .setSize()
working by delaying its execution (as suggested on various forums):
我设法.setSize()
通过延迟执行来完成工作(如各种论坛所建议的那样):
window.setTimeout(function() {
FB.Canvas.setSize();
}, 250);
If you have XFBLM
elements, especially fb:comments
, then you need to parse the page before setting its size
如果您有XFBLM
元素,尤其是fb:comments
,那么您需要在设置其大小之前解析页面
window.setTimeout(function() {
FB.XFBML.parse();
FB.Canvas.setSize();
}, 250);
Note, that you need to run this script after your content block, otherwise increase the time interval (in ms) allowing webserver and client browser building the content before resizing canvas.
请注意,您需要在内容块之后运行此脚本,否则增加时间间隔(以毫秒为单位),允许网络服务器和客户端浏览器在调整画布大小之前构建内容。
This approach only increases the height of your page and doesn't decrease it. You can achieve decreasing manually by firing 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 be blinking due to the double resizing.
但是,有一个缺点 - 由于双重调整大小,页面会闪烁。
Also, one suggests running .setSize
in several time intervals to account delayed content:
此外,有人建议.setSize
在几个时间间隔内运行以考虑延迟的内容:
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 blinky.
在这种情况下,页面和 XFBML 元素变得非常闪烁。
回答by Wes Gamble
We have pages in our iframe that append content to the page and then allow the user to refresh the content within the page in place. In these cases, we saw the same thing, where the content would not shrink when appropriate.
我们的 iframe 中有一些页面可以将内容附加到页面,然后允许用户就地刷新页面内的内容。在这些情况下,我们看到了同样的事情,内容不会在适当的时候缩小。
FB.Canvas.setSize() calls _computeContentSize, which is shown below:
FB.Canvas.setSize() 调用_computeContentSize,如下图:
_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 problematic 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 shrunk, the value of body.offsetHeight will not shrink.
即使你的 iframe 里面的内容缩小了,body.offsetHeight 的值也不会缩小。
To solve this, we made a custom version of the computeContentSize function that only consults the docElement for height, like so:
为了解决这个问题,我们制作了一个自定义版本的 computeContentSize 函数,它只查询 docElement 的高度,如下所示:
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};
}
Anytime we want to resize and know that the content could shrink we'll use the custom function to pass content to setSize (e.g. FB.Canvas.setSize(rfComputeContentSize())), and anytime we know that the content will only grow, we'll use the standard FB.Canvas.setSize() function.
任何时候我们想要调整大小并知道内容可能会缩小,我们将使用自定义函数将内容传递给 setSize(例如 FB.Canvas.setSize(rfComputeContentSize())),并且只要我们知道内容只会增长,我们就会将使用标准的 FB.Canvas.setSize() 函数。
Note that we were using setAutoGrow() and I didn't check, but am assuming that it uses the same function to determine size. We disabled our call to setAutoGrow() and will have to be vigilant about calling setSize() at approrpriate times.
请注意,我们使用的是 setAutoGrow() 并且我没有检查,但我假设它使用相同的函数来确定大小。我们禁用了对 setAutoGrow() 的调用,并且必须警惕在适当的时间调用 setSize()。
Logged this bug with Facebook: https://developers.facebook.com/bugs/228704057203827
用 Facebook 记录了这个错误:https: //developers.facebook.com/bugs/228704057203827
回答by jaset
We ran into an issue where their FB.Canvas
functions didn't work, although everything was properly initialized, because they're using ‘IFRAME' instead of iframe in their cross-domain JS setup, hence no XHTML compatibility.
我们遇到了一个问题,即他们的FB.Canvas
功能不起作用,尽管一切都已正确初始化,因为他们在跨域 JS 设置中使用的是“IFRAME”而不是 iframe,因此没有 XHTML 兼容性。
We fixed this by prototyping our own createElement function and overriding theirs. Just put this right after you include Facebooks all.js:
我们通过对我们自己的 createElement 函数进行原型设计并覆盖他们的来解决这个问题。在你包含 Facebooks all.js 之后把它放在右边:
document.__createElement = document.createElement;
document.createElement = function(tagName) {
return document.__createElement(tagName.toLowerCase());
}
回答by Kelly B
bit of excess functionality, but this article explains why you cant do that dynamically and provides the easiestsolution... http://www.twistermc.com/36764/shrink-facebook-tabs/The answer is simple: Shrink it really small, then after a pause use AutoGrow to make it the correct size... Alice in Wonderland style.
有点多余的功能,但这篇文章解释了为什么你不能动态地做到这一点,并提供了最简单的解决方案...... http://www.twistermc.com/36764/shrink-facebook-tabs/答案很简单:把它缩小得非常小,然后在暂停后使用 AutoGrow 使其成为正确的大小......爱丽丝梦游仙境风格。
- I say easiest because from a dev and user point of view this slows things down by about 1/4 second, and the user gets a tiny flash of the scrollbars...
- 我说最简单,因为从开发人员和用户的角度来看,这会减慢大约 1/4 秒的速度,并且用户会看到滚动条的微小闪光......
回答by Alex Novikov
When resizing to the minimum height do not forget to make it a little bit bigger than it is, to account for horizontal scrolling bar and some extra pixels that some browsers add, otherwise you will end-up with vertical scroll.
当调整到最小高度时,不要忘记让它比实际大一点,以考虑水平滚动条和一些浏览器添加的一些额外像素,否则最终会出现垂直滚动。
Also I do not recommend to use body
to count height.
另外我不建议使用body
来计算高度。
This worked for me :
这对我有用:
window.fbAsyncInit = function()
{FB.Canvas.setSize({height:document.getElementById('m_table').offsetHeight+40});}
where m_table is table ID with all my content (you can use div
instead).
其中 m_table 是包含我所有内容的表 ID(您可以div
改用)。
回答by LocalPCGuy
Bobby's answer is very good. Only thing I would add to it is that some people have had success getting the page to shrink by doing the following:
鲍比的回答非常好。我唯一要补充的是,有些人通过执行以下操作成功地缩小了页面:
FB.Canvas.setSize({ width: 760, height: 10 });
FB.Canvas.setSize({ width: 760, height: 10 });
And then follow it with:
然后跟着它:
FB.Canvas.setAutoResize();
FB.Canvas.setAutoResize();
You don't have to use 10, just something smaller than the minimum size of your page. Then the FB.Canvas.setAutoResize()
should go ahead and make it the proper height again and continue to update. The only time you need to call FB.Canvas.setSize({ width: 760, height: 10 });
again would be if the content shrunk again.
您不必使用 10,只需比页面的最小尺寸小一些即可。然后FB.Canvas.setAutoResize()
应该继续并再次将其设置为适当的高度并继续更新。您唯一需要FB.Canvas.setSize({ width: 760, height: 10 });
再次调用的时间是内容再次缩小时。
The danger of doing this is that if the FB.Canvas.setAutoResize();
doesn't work, you could have content that is cut off.
这样做的危险在于,如果FB.Canvas.setAutoResize();
不起作用,您的内容可能会被切断。
回答by Hendrik
None of this worked for me. Make sure to type 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>
回答by Akkumulator
I tried to use FB.Canvas.setSize(e);
to resize my app, but it did not resize at all.
我试图用来FB.Canvas.setSize(e);
调整我的应用程序的大小,但它根本没有调整大小。
I took a look in the Facebook Javascript and found out, that FB.Canvas.setSize
calls the FB.Arbiter.inform('setSize',e)
function.
我查看了 Facebook Javascript 并发现,它FB.Canvas.setSize
调用了该FB.Arbiter.inform('setSize',e)
函数。
If I call the FB.Arbiter.inform('setSize',{ width: 760, height: 1480 })
function right from my code, the canvas resizes correctly.
如果我FB.Arbiter.inform('setSize',{ width: 760, height: 1480 })
直接从我的代码中调用该函数,画布会正确调整大小。
回答by Floyd Wilburn
This has worked for me:
这对我有用:
<script type='text/javascript'>
window.onload=function() {
FB.Canvas.setSize({width:760,height:document.body.offsetHeight});
}
</script>
Note that you don't need FB.init unless you are using it for other reasons.
请注意,除非您出于其他原因使用它,否则您不需要 FB.init。