Pergunta

Eu tenho o seguinte script, onde o primeiro eo terceiro document.writeline são estáticas e o segundo é gerado :

<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script language='javascript' type='text/javascript'>alert('during');<\/sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

O Firefox e Chrome irá exibir antes , durante e após , enquanto o Internet Explorer primeiros shows durante e só em seguida, ele mostra antes e após .

Eu me deparei um artigo que os Estados que eu não sou o primeiro a encontrar esse, mas isso não me faz sentir melhor.

Alguém sabe como posso definir a fim de ser determinista em todos os navegadores, ou cortar o IE para o trabalho como todos os outros, navegadores sãs fazer?

Advertências : O trecho de código é um repro muito simples. É gerado no servidor e o segundo script é a única coisa que muda. É um roteiro muito tempo ea razão existem dois scripts antes e depois dele são para que o navegador irá armazenar em cache-los e a parte dinâmica do código vai ser tão pequena quanto possível. Pode também aparece muitas vezes na mesma página com código gerado diferente.

Foi útil?

Solução 2

Eu encontrei uma resposta mais ao meu gosto:

<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script defer language='javascript' type='text/javascript'>alert('during');<\/sc" + "ript>");
document.write("<script defer language='javascript' type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

Isto irá adiar o carregamento de ambos durante e após até que a página tem carregamento acabado.

Eu acho que isso é tão bom quanto eu posso começar. Felizmente, alguém vai ser capaz de dar uma resposta melhor.

Outras dicas

Não, este é o comportamento do Internet Explorer.

Se você anexar scripts de forma dinâmica, IE, Firefox e Chrome tudo vai baixar os scripts de forma assíncrona.

O Firefox e Chrome vai esperar até todo o assíncrono solicitações de retorno e, em seguida, executará os scripts na ordem em que eles estão ligados no DOM, mas IE executa os scripts na ordem em que eles são devolvidos ao longo do fio.

Desde o alerta leva menos tempo para "recuperar" do que um arquivo javascript externo, que provavelmente explica o comportamento que você está vendo.

De Kristoffer Henriksson do pós sobre o tema da assíncrona script de carregamento :

Neste cenário IE e Firefox vontade baixar ambos os scripts, mas Internet Explorer também irá executá-los na ordem em que terminar o download em enquanto o Firefox transfere-los de forma assíncrona, mas ainda executa-los na ordem em que são ligados no DOM.

No Internet Explorer isso significa que seu scripts não pode ter dependências em uns aos outros como a ordem de execução irá variar dependendo da rede tráfego, caches, etc.

Considere o uso de um carregador de Javascript. Ele permitirá que você especificar dependências de script e ordem de execução ao mesmo tempo, carregar seus scripts de forma assíncrona para a velocidade, bem como suavizar algumas das diferenças navegador.

Esta é uma visão muito boa de alguns deles: JavaScript essencial:. topo cinco carregadores de script

Eu usei ambos RequireJS e LabJS. Na minha opinião, LabJS é um pouco menos opinativo.

Slides 25/26 de talk esta apresentação sobre as características de diferentes métodos para a inserção de scripts. Ele sugere que o IE é o único navegador que irá executar esses scripts em ordem. Todos os outros navegadores irá executá-los na ordem em que eles concluir o carregamento. Mesmo IE não vai executá-los em ordem, se um ou mais têm js em linha em vez de um src.

Um dos métodos sugeridos é para inserir um novo elemento DOM:

var se1 = document.createElement('script');
se1.src = 'a.js';

var se2 = document.createElement('script');
se2.src = 'b.js';

var se3 = document.createElement('script');
se3.src = 'c.js';

var head = document.getElementsByTagName('head')[0]
head.appendChild(se1);
head.appendChild(se2);
head.appendChild(se3);

Para fazer a segunda seção script gerado você pode usar um script para gerar o conteúdo e passar os parâmetros:

se2.src = 'generateScript.php?params=' + someParam;

EDIT: A despeito do que o artigo I situada diz, meu teste sugere que a maioria dos navegadores irá executar seus scripts document.write em ordem, se cada um deles tem um src, por isso, enquanto eu acho que o método acima é o preferido, você poderia fazer isso também:

<script language="javascript" type="text/javascript">
document.write("<script type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

EDIT novamente (resposta aos comentários a mim e aos outros): Você já está gerando o script em sua página. O que quer que você está fazendo pode ser movido para outro script do lado do servidor que gera o mesmo bloco de código. Se você precisa de parâmetros em sua página, em seguida, passá-las para o script na cadeia de consulta.

Além disso, você pode usar este mesmo método se, como você sugere, você está gerando as várias vezes script embutido:

<script language="javascript" type="text/javascript">
document.write("<script type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params1 + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params2 + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params3 + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

No entanto, isso está começando a parecer como se você está se aproximando desta forma o errado. Se você estiver gerando um grande bloco de vários código de vezes, então você provavelmente deve ser substituindo-o por um único js função e chamá-lo com diferentes parâmetros em vez ...

Tudo bem ... durante ...

// During.js
during[fish]();

depois ...

// After.js
alert("After");
fish++

HTML

<!-- some html -->
<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript'>during[" + fish + "] = function(){alert('During!' + fish);}</sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='during.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'></sc" + "ript>");
</script>
<!-- some other html -->
<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript'>during[" + fish + "] = function(){alert('During!' + fish);}</sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='during.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'></sc" + "ript>");
</script>

Estou inclinado a concordar sobre a forma como isso está começando a cheiro, no entanto. Em particular, por que não poderia você CodeGen o "durante" em um arquivo criado dinamicamente js e inserção que?

Note que o script gerado dinamicamente vai dentro a função no segunda document.write.
Testado em FF2, IE7

Você pode forçar a execução secuential definindo "onload" (ou similar) eventos os scripts e injetar o próximo na função evento. Não é trivial, mas há uma abundância de exemplos lá fora, aqui é um deles.

http://www.phpied.com/javascript-include-ready- onload /

Eu acho que as bibliotecas populares como jQuery ou protótipo pode ajudar com isso.

Código de fornecer:

<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript'>function callGeneratedContent() { alert('during'); }<\x2Fscript>");
document.write("<script language='javascript' type='text/javascript' src='before.js'><\x2Fscript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'><\x2Fscript>");
</script>

Em before.js:

alert("Before");
callGeneratedContent();

Em after.js:

alert("After");

Você tem que colocar a linha gerado primeiro, caso contrário FF vai reclamar porque ele executa before.js antes de ver a definição da função.

Como sobre isso:

<script>
document.write("<script src='before.js'><\/script>");
</script>

<script >
document.write("<script>alert('during');<\/script>");
</script>

<script>
document.write("<script src='after.js'><\/script>");
</script>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top