O $ (document) .ready () também está pronto para CSS?

Eu tenho um script em execução no $ (document) .ready () que deveria alinhar verticalmente o elemento de bloco no meu layout. 90% do tempo, funciona sem problemas. No entanto, para esse 10% extra, uma das duas coisas acontece:

Existe alguma razão pela qual a execução de um script em DOM-ready não teria todos os valores de CSS corretos injetados no DOM ainda? (todo o CSS está no através de um ).

Além disso, aqui está o script que está causando o problema (sim, foi tirado direto daqui ):

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

Obrigado.

Das notas de lançamento do 1.3 :

O método ready () não tenta mais garantir a espera de que todas as folhas de estilo sejam carregadas. Em vez disso, todos os arquivos CSS devem ser incluídos antes dos scripts na página. Mais Informações

Da documentação pronta (fn) :

Nota: Por favor, certifique-se de que todas as folhas de estilo estão incluídas antes de seus scripts (especialmente aqueles que chamam a function pronta). Isso fará com que todas as propriedades do elemento sejam definidas corretamente antes que o código do jQuery comece a ser executado. Não fazer isso causará problemas esporádicos, especialmente em navegadores baseados no WebKit, como o Safari.

Note que o acima não é mesmo renderizar o CSS, então você ainda pode ver a canvas mudar quando ready() entra em ação. Mas isso deve evitar problemas.

Na verdade, acho um pouco estranho que apenas colocar o CSS acima do JS resolva todos os problemas. O CSS é carregado de forma assíncrona, portanto, o carregamento do JS pode iniciar e terminar enquanto o CSS ainda está sendo baixado. Portanto, se o acima for uma solução, a execução de qualquer código JS será interrompida até que todas as solicitações anteriores sejam concluídas?

Fiz alguns testes e, de fato, às vezes o JS é atrasado até que o CSS seja carregado. Eu não sei porque, porque a cachoeira mostra que o JS completou o carregamento muito antes de baixar o CSS terminou.

Veja JS Bin para alguns HTML e seus resultados (isso tem um atraso de 10 segundos), e veja webpagetest.org para seus resultados de cascata . Isso usa algum script do cuzillion.com de Steve Souders para imitar respostas lentas. Na cachoeira, a referência ao resource.cgi é o CSS. Portanto, no Internet Explorer, o primeiro JS externo começa a ser carregado logo após o CSS ser solicitado (mas esse CSS levará outros 10 segundos para ser concluído). Mas a segunda tag não é executada até que o CSS tenha terminado de carregar também:

    

Cachoeira com um único script JS externo

Outro teste com um segundo JS externo após obter o jQuery, mostra que o download do segundo JS não é iniciado até que o CSS seja carregado. Aqui, a primeira referência ao resource.cgi é o CSS, o segundo o JS:

Cachoeira com dois scripts JS externos

Mover a folha de estilo abaixo de todo o JS realmente mostra que o JS (incluindo a function ready ) é executado muito antes, mas mesmo assim a class aplicada ao jQuery - que ainda é desconhecida quando o JS é executado-- é usada corretamente nos meus testes rápidos no Safari e o Firefox. Mas faz sentido que coisas como $(this).height() produzam valores errados naquele momento.

No entanto, testes adicionais mostram que não é uma regra genérica que o JS é interrompido até que o CSS definido anteriormente seja carregado . Parece haver alguma combinação com o uso de JS e CSS externos. Eu não sei como isso funciona.

Últimas annotations: como o JS Bin inclui o Google Analytics em cada script ao ser executado a partir do URL simples (como jsbin.com/aqeno , os resultados do teste são realmente alterados pelo JS Bin ... Parece que a guia Saída no URL de edição, como O jsbin.com/aqeno/edit não inclui as coisas adicionais do Google Analytics, e certamente produz resultados diferentes, mas é difícil testar o URL usando o webpagetest.org A referência aos Blocos de Estilo bloqueia os downloads no Firefox e na Execução de JavaScript no IE como dada por strager é um bom começo para uma melhor compreensão, mas ainda tenho muitas perguntas ... Além disso, observe o carregamento paralelo do script IE8 de Steve Souders para tornar as coisas ainda mais complicadas (as cascatas acima são criadas usando o IE7).

Talvez se deva simplesmente acreditar nas notas de lançamento e documentação ...

A ordenação de CSS / JavaScript / JQuery não funciona para mim, mas o seguinte faz:

 $(window).load(function() { $('#abc')...} ); 

O DOM pronto triggers quando todos os nós do DOM estão disponíveis. Não tem nada a ver com CSS. Tente posicionar o estilo antes ou tente carregá-lo de maneira diferente.

Até onde sei, o evento pronto é acionado quando o DOM é carregado – o que significa que todas as solicitações de bloqueio (ou seja, JS) foram carregadas e a tree DOM é completamente representada graficamente. O estado pronto no IE depende de um gatilho de evento mais lento (document.readyState change vs DOMContentLoaded) do que a maioria dos outros navegadores, portanto, o tempo também depende do navegador.

A existência de solicitações sem bloqueio (como CSS e imagens) é completamente assíncrona e não está relacionada ao estado pronto. Se você está em uma posição onde você precisa de tais resources, você precisa depender do bom e velho evento onload.

De acordo com o HTML5, DOMContentLoaded é um evento pronto para DOM simples, sem levar em conta as folhas de estilo. No entanto , o algoritmo de análise HTML5 exige que os navegadores adiem a execução de scripts até que todas as folhas de estilo anteriores sejam carregadas. ( DOMContentLoaded e folhas de estilo )

Nos testes de molily (2010) ,

  • IE e Firefox bloquearam toda a execução de scripts subseqüentes até que as folhas de estilo sejam carregadas
  • O Webkit bloqueou a execução subsequente apenas para scripts externos ( )
  • O Opera não bloqueou a execução subseqüente de nenhum script

Todos os navegadores modernos agora suportam DOMContentLoaded (2017), portanto, eles podem ter padronizado esse comportamento até agora.