如何正确调整 Facebook Canvas 应用程序 (iFrame) 的大小?

发布于 2024-10-12 06:16:19 字数 1409 浏览 8 评论 0原文

我需要在更新页面内容后调整画布大小。我可以明确地做到这一点

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

,但是,如果没有参数,即 .setSize(),它就无法工作。

另外,我可以通过但只能增加来调整高度

FB.Canvas.setAutoResize(true);

- 当内容减少时它不会减少高度。

以下行不起作用:

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

如何使其工作?

关于该主题的更多评论:

  1. http://developers.facebook.com/blog/post/93
  2. http://developers.facebook.com/docs/参考/javascript/fb.canvas.setautoresize

相关:

  1. facebook-api:Facebook Connect 跨域接收者 URL 是什么?
  2. facebook-app:如何更改可调整大小的 iframe 应用程序的高度?
  3. 动态设置画布尺寸时调整大小时文档高度会增加

如何控制 Facebook Canvas 应用的大小?

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().

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:

  1. http://developers.facebook.com/blog/post/93
  2. http://developers.facebook.com/docs/reference/javascript/fb.canvas.setautoresize

Related:

  1. facebook-api: what's Facebook Connect cross-domain receiver URL?
  2. facebook-app: how can i change the height of a resizeable iframe application?
  3. Document height grows on resize when setting canvas dimensions dynamically

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

清引 2024-10-19 06:16:19

不要编写自己的定时自动调整大小函数。 Facebook 有一个:

FB.Canvas.setAutoResize();

如果你知道何时需要调整它的大小

FB.Canvas.setSize()

,那么,如果你想在单击链接时变小,请将其粘贴到一个函数中,然后稍后调用该函数,例如:

function sizeChangeCallback() {
    FB.Canvas.setSize();
  }

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

你不需要设置明确的高度,但有时您可能会遇到动态 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.setAutoResize/

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

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:

   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/

放手` 2024-10-19 06:16:19

我已经设法通过延迟执行来使 .setSize() 工作(如各个论坛上的建议):

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

如果您有 XFBLM 元素,尤其是 fb:comments< /code>,那么您需要在设置其大小之前解析页面

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

注意,您需要在内容块之后运行此脚本,否则增加时间间隔(以毫秒为单位),允许网络服务器和客户端浏览器在调整画布大小之前构建内容。

这种方法只会增加页面的高度,而不会减少页面的高度。您可以通过在上面的代码之前触发以下行来手动减小大小

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

,但是,有一个缺点 - 由于双重调整大小,页面将闪烁。

另外,建议在几个时间间隔内运行 .setSize 以考虑延迟的内容:

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

在这种情况下,页面和 XFBML 元素变得相当闪烁。

I have managed to make .setSize() working by delaying its execution (as suggested on various forums):

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

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:

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.

苏别ゝ 2024-10-19 06:16:19

我们的 iframe 中有一些页面将内容附加到页面,然后允许用户刷新页面内的内容。在这些情况下,我们看到了同样的情况,即内容不会在适当的时候缩小。

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

有问题的行在这里:

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

即使 iframe 内的内容缩小了,body.offsetHeight 的值也不会缩小。

为了解决这个问题,我们制作了一个自定义版本的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};
}

每当我们想要调整大小并知道内容可能缩小时,我们都会使用自定义函数将内容传递给setSize(例如FB.Canvas.setSize(rfComputeContentSize())),只要我们知道内容只会增长,我们就会使用标准 FB.Canvas.setSize() 函数。

请注意,我们使用的是 setAutoGrow(),我没有检查,但假设它使用相同的函数来确定大小。我们禁用了对 setAutoGrow() 的调用,并且必须在适当的时间调用 setSize() 保持警惕。

通过 Facebook 记录此错误:https://developers.facebook.com/bugs/228704057203827

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.

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

To solve this, we made a custom version of the computeContentSize function that only consults the docElement for height, like so:

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.

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.

Logged this bug with Facebook: https://developers.facebook.com/bugs/228704057203827

川水往事 2024-10-19 06:16:19

我们遇到了一个问题,尽管一切都已正确初始化,但他们的 FB.Canvas 功能不起作用,因为他们在跨域 JS 设置中使用“IFRAME”而不是 iframe,因此没有XHTML 兼容性。

我们通过构建自己的 createElement 函数原型并覆盖他们的函数来解决这个问题。
只需将其放在包含 Facebook all.js 之后即可:

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

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.

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

document.__createElement = document.createElement;
document.createElement = function(tagName) {
            return document.__createElement(tagName.toLowerCase());
}
黑白记忆 2024-10-19 06:16:19

有点多余的功能,但本文解释了为什么你不能动态地做到这一点,并提供了最简单的解决方案......
http://www.twistermc.com/36764/shrink-facebook-tabs/
答案很简单:
将其缩小得很小,然后暂停后使用自动增长使其达到正确的尺寸...爱丽丝梦游仙境风格。

  • 我说最简单是因为从开发者和用户的角度来看,这会减慢大约 1/4 秒的速度,并且用户会看到滚动条的微小闪烁......

bit of excess functionality, but this article explains why you cant do that dynamically and provides the easiest solution...
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.

  • 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...
淤浪 2024-10-19 06:16:19

鲍比的回答非常好。我唯一要补充的是,有些人通过执行以下操作成功地缩小了页面:

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

然后后面加上:

FB.Canvas.setAutoResize();

您不必使用 10,只需使用比页面最小尺寸更小的值即可。然后 FB.Canvas.setAutoResize() 应该继续并再次使其达到正确的高度并继续更新。唯一一次需要再次调用 FB.Canvas.setSize({ width: 760, height: 10 }); 的情况是内容再次缩小。

这样做的危险在于,如果FB.Canvas.setAutoResize();不起作用,您的内容可能会被切断。

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

And then follow it with:

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.

The danger of doing this is that if the FB.Canvas.setAutoResize(); doesn't work, you could have content that is cut off.

夜血缘 2024-10-19 06:16:19

这些对我来说都不起作用。确保在结束标记之前键入此内容。

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

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>    
远山浅 2024-10-19 06:16:19

我尝试使用 FB.Canvas.setSize(e); 来调整我的应用程序的大小,但它根本没有调整大小。

我查看了 Facebook Javascript,发现 FB.Canvas.setSize 调用了 FB.Arbiter.inform('setSize',e) 函数。

如果我直接从代码中调用 FB.Arbiter.inform('setSize',{ width: 760, height: 1480 }) 函数,则画布会正确调整大小。

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

I took a look in the Facebook Javascript and found out, that FB.Canvas.setSize calls the FB.Arbiter.inform('setSize',e) function.

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

探春 2024-10-19 06:16:19

这对我有用:

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

请注意,除非您出于其他原因使用它,否则不需要 FB.init。

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.

马蹄踏│碎落叶 2024-10-19 06:16:19

当调整到最小高度时,不要忘记使其比实际大一点,以考虑水平滚动条和某些浏览器添加的一些额外像素,否则您最终将得到垂直滚动。

另外我不建议使用 body 来计算高度。

这对我有用:

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

其中 m_table 是包含我所有内容的表 ID(您可以使用 div 代替)。

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.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文