Как правильно изменить размер приложения Facebook Canvas (iFrame)? - PullRequest
7 голосов
/ 15 января 2011

Мне нужно настроить размер холста после обновления содержимого страницы. Я могу сделать это явно с помощью

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/reference/javascript/fb.canvas.setautoresize

Связанный:

  1. facebook-api: что такое междоменный URL-адрес получателя Facebook Connect?
  2. facebook-приложение: как я могу изменить высоту изменяемого размера приложения iframe?
  3. Высота документа увеличивается при изменении размера при динамической настройке размеров холста

Как вы контролируете размер приложений Facebook Canvas?

Ответы [ 10 ]

7 голосов
/ 31 марта 2011

Не пишите свою собственную функцию для автоматического изменения размера по времени.Fb имеет один:

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/

3 голосов
/ 15 января 2011

Мне удалось заставить .setSize() работать, задержав его выполнение (как предлагалось на разных форумах):

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

Если у вас есть XFBLM элементов, особенно fb:comments, то вам нужно проанализировать страницу перед установкой ее размера

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 становятся довольно мигающими.

2 голосов
/ 04 января 2012

В нашем 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

1 голос
/ 20 июля 2012

немного избыточной функциональности, но в этой статье объясняется, почему вы не можете сделать это динамически, и предоставляется самое простое решение ... http://www.twistermc.com/36764/shrink-facebook-tabs/ Ответ прост: уменьшите его очень маленьким, затем послепауза, используя AutoGrow, чтобы сделать правильный размер ... Алиса в стиле чудес.

  • Я говорю проще всего, потому что с точки зрения разработчика и пользователя это замедляет процесс примерно на 1/4 секунды,и пользователь получает крошечную вспышку полос прокрутки ...
1 голос
/ 24 мая 2012

Мы столкнулись с проблемой, когда их FB.Canvas функции не работали, хотя все было правильно инициализировано, потому что они используют IFRAME вместо iframe в своей междоменной установке JS, следовательно, не совместимы с XHTML.

Мы исправили это, создав прототип нашей собственной функции createElement и переопределив ее.Просто вставьте это сразу после того, как вы включили в Facebook all.js:

document.__createElement = document.createElement;
document.createElement = function(tagName) {
            return document.__createElement(tagName.toLowerCase());
}
0 голосов
/ 03 июля 2012

При изменении размера до минимальной высоты не забудьте сделать его немного больше, чем он есть, чтобы учесть горизонтальную полосу прокрутки и некоторые дополнительные пиксели, которые добавляют некоторые браузеры, в противном случае вы в конечном итоге получите вертикальную прокрутку.

Также я не рекомендую использовать body для подсчета высоты.

Это сработало для меня:

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

где m_table - это идентификатор таблицы со всем моим контентом (вместо этого вы можете использовать div).

0 голосов
/ 15 сентября 2011

Это работает для меня:

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

Обратите внимание, что вам не нужен FB.init, если вы не используете его по другим причинам.

0 голосов
/ 15 сентября 2011

Я пытался использовать FB.Canvas.setSize(e); для изменения размера моего приложения, но оно не изменилось вообще.

Я заглянул в JavaScript Javascript и обнаружил, что FB.Canvas.setSize вызывает функцию FB.Arbiter.inform('setSize',e).

Если я вызываю функцию FB.Arbiter.inform('setSize',{ width: 760, height: 1480 }) прямо из моего кода, холст изменяет размер правильно.

0 голосов
/ 31 августа 2011

Ничего из этого не сработало для меня.Обязательно наберите это перед закрывающим тегом.

<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 голосов
/ 02 мая 2011

Ответ Бобби очень хороший.Единственное, что я хотел бы добавить к этому, это то, что некоторые люди добились успеха в уменьшении страницы, выполнив следующее:

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

И затем добавьте:

FB.Canvas.setAutoResize();

Вам не нужно использовать 10, просто что-то меньше, чем минимальный размер вашей страницы.Затем FB.Canvas.setAutoResize() должен продолжить и снова установить нужную высоту и продолжить обновление.Единственный раз, когда вам нужно будет снова вызывать FB.Canvas.setSize({ width: 760, height: 10 });, будет, если содержимое снова уменьшится.

Опасность этого заключается в том, что если FB.Canvas.setAutoResize(); не работает, у вас может быть отрезанный контент.

...