Почему, по-видимому, reflow DOM встречает элементы <fb: xxx> fbml при правильном использовании xmlns fbml?

У меня есть страница, содержащая несколько кнопок facebook "Like", встроенных с использованием встроенного метода fbml (в отличие от iframe). Достаточно просто. Страница отображается отлично, все работает так, как ожидалось.

ОДНАКО...

Как только я добавлю объявление пространства имен xmlns:fb="http://www.facebook.com/2008/fbml" в документ, я замечаю радикальное ухудшение начального времени визуализации страницы в IE. Более тщательный осмотр (с использованием инструментов разработчика ie8) показывает, что вся DOM снова "обновляется" или "перепланируется" снова и снова, в течение короткого периода после начальной загрузки страницы. Некоторые дополнительные ошибки показывают, что количество переходов, по-видимому, пропорционально количеству элементов <fb:xxx> в документе.

Удаление объявления xmlns устраняет проблему.

Кто-нибудь испытал это раньше?

ОБНОВЛЕНИЕ:

Некоторые дальнейшие копания выявили еще некоторые особенности... Проблема в том, что IE пересматривает страницу, включая повторное выполнение любых встроенных скриптов и т.д. Причиной не является включение самих xmlns, а скорее рендеринг xfbml самих кнопок. Добавление xmlns просто вызвало рендеринг xfbml без xmlns, кнопки никогда не отображались в первую очередь. Следующая заметка иллюстрирует проблему.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" xmlns:fb="http://www.facebook.com/2008/fbml">
  <head>  
    <script type="text/javascript">
      alert('some inline js');
    </script>
  </head>
  <body>
    <div id="fb-root"></div>

    <div>
      <fb:like href="#" onclick="location.href='http://example.local/1'; return false;" layout="button_count" show_faces="false" width="80" action="like" font="arial" colorscheme="light"></fb:like>
      <fb:like href="#" onclick="location.href='http://example.local/2'; return false;" layout="button_count" show_faces="false" width="80" action="like" font="arial" colorscheme="light"></fb:like>
      <fb:like href="#" onclick="location.href='http://example.local/3'; return false;" layout="button_count" show_faces="false" width="80" action="like" font="arial" colorscheme="light"></fb:like>
    </div>

    <script src="http://connect.facebook.net/en_US/all.js#xfbml=1" type="text/javascript"></script>

  </body>
</html>

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

Ответ 1

Кажется, вы испытываете фейсбук ошибка 9777. Это было с самого начала нового all.js. Я думаю, что было несколько попыток исправить это, что на самом деле не сработало. Похоже, что на прошлой неделе приоритет был поднят на более высокий уровень. Посмотрим, будет ли он исправляться в ближайшее время.

В любом случае проблема, которую вы видите, не вызвана изменением дерева DOM. На самом деле, запуск javascript даже не на вашей странице... ваша "верхняя" страница.

script находится в фреймах, созданных facebook script вместо ваших элементов fb:like.

Вместо "некоторых встроенных js", если ваш alert показывает следующее:

alert("This: " + window.location.href + "\nTop: " + window.top.location.href);

вы увидите, откуда он. В URL "This" вы увидите fb_xd_fragment вместе с целым рядом параметров, добавленных к вашему URL-адресу. В принципе, facebook script перенаправляет каждое окно iframe на URL-адреса, которые вы видите, которые запускают ваши скрипты.

В http://developers.facebook.com/docs/reference/javascript/FB.init/ они обсуждают URL-адрес настраиваемого канала (channelURL) как обходной путь, который, похоже, не имеет работал для многих людей. И многие люди получают запрос наводнения на пути, который они предоставляют в качестве каналаURL.

 

Просто мысль... Вы пробовали загружать кнопки "как", используя метод iframe? Было ли это быстрее?

В противном случае вы можете попробовать ленивую загрузку all.js script...

(function() {
  var e = document.createElement('script');
  e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js#xfbml=1';
  e.async = true;
  document.getElementById('fb-root').appendChild(e);
}());