Является ли $ (document) .ready () также готовым CSS? - PullRequest
47 голосов
/ 25 августа 2009

У меня есть скрипт, выполняющийся на $ (document) .ready (), который должен вертикально выровнять блочный элемент в моем макете. 90% времени, это работает без проблем. Однако за эти дополнительные 10% происходит одно из двух:

  • Существует очевидная задержка во времени, необходимом для центрирования, и элементы блока переходят в нужное положение. Это может быть просто связано с производительностью - поскольку размер страницы часто велик, и за один раз выполняется довольно много javascript.

  • Центрирование полностью испортится, и элемент блока будет либо отталкиваться слишком далеко, либо недостаточно далеко. Похоже, что он пытался вычислить высоту, но получал неправильные измерения.

Есть ли какая-то причина, по которой при выполнении сценария в DOM-ready все правильные значения CSS не будут внедрены в DOM? (весь CSS находится в <head> через <link>).

Кроме того, вот сценарий, который вызывает проблему (да, он был взят прямо из здесь ):

 (function ($) {
    // VERTICALLY ALIGN FUNCTION
    $.fn.vAlign = function() {
      return this.each(function(i) {
        var ah = $(this).height();
        var ph = $(this).parent().height();
        var mh = (ph - ah) / 2;
        $(this).css('margin-top', mh);
      });
    };
  })(jQuery);

Спасибо.

Ответы [ 5 ]

62 голосов
/ 25 августа 2009

Из примечаний к выпуску 1.3 :

Метод ready () больше не пытается дать какие-либо гарантии ожидания загрузки всех таблиц стилей. Вместо этого все CSS-файлы должны быть включены перед сценариями на странице. Дополнительная информация

Из документации ready (fn) :

Примечание. Пожалуйста, убедитесь, что все таблицы стилей включены перед вашими сценариями (особенно те, которые вызывают функцию ready). Это обеспечит правильное определение всех свойств элемента перед началом выполнения кода jQuery. Невыполнение этого требования может вызвать спорадические проблемы, особенно в браузерах на основе WebKit, таких как Safari.

Обратите внимание, что вышесказанное даже не касается рендеринга CSS, поэтому вы все равно можете увидеть изменение экрана при включении ready(). Но это должно уберечь вас от проблем.

На самом деле, я нахожу немного странным, что простое размещение CSS над JS решит все проблемы. CSS загружается асинхронно, поэтому загрузка JS может начинаться и заканчиваться , пока CSS еще загружается. Таким образом, если вышеупомянутое является решением, тогда выполнение любого кода JS затем останавливается до тех пор, пока все более ранние запросы не будут выполнены?

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

См. JS Bin для , немного HTML и его результаты (с 10-секундной задержкой), и см. Webpagetest.org для результаты его водопада . Это использует некоторый сценарий от cuzillion.com Стива Соудерса для имитации медленных ответов. В водопаде ссылка на resource.cgi - это CSS. Итак, в Internet Explorer первый внешний JS начинает загружаться сразу после запроса CSS (но этот CSS займет еще 10 секунд). Но второй тег <script> не выполняется, пока не завершится загрузка CSS:

<link rel="stylesheet" type="text/css" href=".../a script that delays.cgi" />

<script type="text/javascript" src=".../jquery.min.js"></script> 

<script type="text/javascript"> 
  alert("start after the CSS has fully loaded"); 
  $(document).ready(function() { 
    $("p").addClass("sleepcgi"); 
    alert("ready"); 
  });         
</script> 

Waterfall with a single external JS script

Еще один тест со вторым внешним JS после получения jQuery, показывает , что загрузка второго JS не начинается, пока не загрузится CSS. Здесь первая ссылка на resource.cgi - это CSS, вторая - на JS:

Waterfall with two external JS scripts

Перемещение таблицы стилей ниже . Все JS действительно показывают, что JS (включая функцию ready) выполняется намного раньше, но даже тогда применяется класс jQuery, который еще неизвестен при запуске JS. - правильно используется в моих быстрых тестах в Safari и Firefox. Но имеет смысл, что такие вещи, как $(this).height() будут давать неправильные значения в то время.

Однако дополнительное тестирование показывает, что не является общим правилом, когда JS останавливается до тех пор, пока не будет загружен ранее определенный CSS . Кажется, есть некоторая комбинация с использованием внешних JS и CSS. Я не знаю, как это работает.

Последнее примечание: поскольку JS Bin включает в себя Google Analytics в каждом сценарии при запуске с чистого URL-адреса (например, jsbin.com / aqeno , , результаты теста фактически изменяются JS Bin ... Похоже, что вкладка "Вывод" на URL-адресе для редактирования, например jsbin.com / aqeno / edit , не включает в себя дополнительные элементы Google Analytics и, безусловно, дает другие результаты, но этот URL сложно протестировать использование webpagetest.org Ссылка на Загрузка блоков стилей в Firefox и JavaScript Выполнение в IE , как указано strager , является хорошим началом для лучшего понимания, но у меня осталось много вопросов. .. Также обратите внимание на то, что Steve Souders '1082 * IE8 Parallel Script Loading загружает , чтобы сделать вещи еще более сложными. (Приведенные выше водопады создаются с использованием IE7.)

Может быть, стоит просто поверить примечаниям к выпуску и документации ...

15 голосов
/ 27 апреля 2012

CSS / JavaScript / JQuery упорядочение не работает для меня, но следующее делает:

$(window).load(function() { $('#abc')...} );
6 голосов
/ 25 августа 2009

DOM ready срабатывает, когда все узлы DOM доступны. Это не имеет ничего общего с CSS. Попробуйте расположить стиль раньше или загрузите его по-другому.

4 голосов
/ 07 октября 2013

Согласно HTML5, DOMContentLoaded - это простое событие, готовое к DOM, без учета таблиц стилей. Однако , алгоритм синтаксического анализа HTML5 требует, чтобы браузеры откладывали выполнение сценариев до загрузки всех предыдущих таблиц стилей. ( DOMContentLoaded и таблицы стилей )

В тестах Молли (2010) ,

  • IE и Firefox блокировали все последующее выполнение скрипта до загрузки таблиц стилей
  • Webkit заблокировал последующее выполнение только для внешних скриптов (<script src>)
  • Opera не блокировала последующее выполнение ни одного скрипта

Все современные браузеры теперь поддерживают DOMContentLoaded (2017), поэтому они, возможно, уже стандартизировали это поведение.

4 голосов
/ 25 августа 2009

Насколько я знаю, событие готовности вызывается при загрузке DOM - это означает, что все запросы на блокировку (т.е. JS) были загружены и дерево DOM полностью отображено. Состояние готовности в IE основано на более медленном триггере события (изменение document.readyState и DOMContentLoaded), чем в большинстве других браузеров, поэтому время также зависит от браузера.

Наличие неблокирующих запросов (таких как CSS и изображения) полностью асинхронно и не связано с состоянием готовности. Если вы находитесь в положении, когда вам требуются такие ресурсы, вам нужно зависеть от старого доброго события onload.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...