How to resize Facebook Canvas app (iFrame) correctly?

前端 未结 10 586
走了就别回头了
走了就别回头了 2021-02-06 09:25

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

howev

10条回答
  •  既然无缘
    2021-02-06 09:49

    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

提交回复
热议问题