Por que o document.write é considerado uma “prática ruim”?

Eu sei document.write é considerado uma má prática; e espero compilar uma lista de motivos para enviar a um fornecedor de terceiros o motivo pelo qual eles não devem usar o document.write nas implementações de seu código de análise.

Por favor inclua o seu motivo para reivindicar o document.write Escreva como uma má prática abaixo.

Alguns dos problemas mais sérios:

  • document.write (daqui em diante DW) não funciona em XHTML

  • O DW não modifica diretamente o DOM, impedindo a manipulação adicional (tentando encontrar evidências disso, mas é na melhor das hipóteses situacional)

  • DW executado após o término do carregamento da página sobrescreverá a página ou escreverá uma nova página ou não funcionará

  • DW executa onde encontrou: não pode injetar em um determinado ponto de nó

  • O DW está efetivamente escrevendo texto serializado que não é a maneira como o DOM funciona conceitualmente, e é uma maneira fácil de criar bugs (.innerHTML tem o mesmo problema)

É muito melhor usar os methods de manipulação DOM seguros e compatíveis com DOM

Na verdade, não há nada errado com document.write , por si só. O problema é que é muito fácil abusar dele. Grosseiramente, até.

Em termos de fornecedores que fornecem código de análise (como o Google Analytics), é na verdade a maneira mais fácil de distribuir esses snippets

  1. Mantém os scripts pequenos
  2. Eles não precisam se preocupar em sobrescrever events onload já estabelecidos ou include a abstração necessária para adicionar events onload com segurança
  3. É extremamente compatível

Contanto que você não tente usá-lo depois que o documento for carregado, document.write não é inerentemente mau, na minha humilde opinião.

Outro uso legítimo de document.write vem do exemplo HTML5 Boilerplate index.html .

    

Também vi a mesma técnica para usar o polyfill JSON parse / stringify do json2.js ( necessário pelo IE7 e abaixo ).

  

Pode bloquear sua página

document.write funciona apenas enquanto a página está sendo carregada; Se você ligar depois que a página terminar de carregar, ela replaceá a página inteira.

Isso significa efetivamente que você precisa chamá-lo de um bloco de script embutido – o que impedirá que o navegador processe partes da página a seguir. Scripts e Imagens não serão baixados até que o bloco de escrita seja concluído.

Pró:

  • É a maneira mais fácil de incorporar conteúdo in-line de um script externo (ao seu host / domínio).
  • Você pode replace todo o conteúdo em um frame / iframe. Eu costumava usar muito essa técnica para peças de menu / navegação antes que as técnicas mais modernas do Ajax estivessem amplamente disponíveis (1998-2002).

Vigarista:

  • Ele serializa o mecanismo de renderização para pausar até que o script externo seja carregado, o que pode levar muito mais tempo do que um script interno.
  • Geralmente é usado de tal forma que o script é colocado dentro do conteúdo, que é considerado de má forma.

Aqui está o meu valor de twopence, em geral você não deve usar document.write para o trabalho pesado, mas há uma instância em que é definitivamente útil:

http://www.quirksmode.org/blog/archives/2005/06/three_javascrip_1.html

Eu descobri isso recentemente tentando criar uma galeria de controle deslizante AJAX. Eu criei dois divs nesteds e apliquei width / height e overflow: hidden para o exterior

com JS. Isso foi para que, no caso de o navegador ter o JS desabilitado, o div flutuasse para acomodar as imagens na galeria – alguma degradação agradável e graciosa.

Coisa é, como com o artigo acima, este seqüestro de JS do CSS não entrou em ação até que a página tivesse carregado, causando um flash momentâneo como o div foi carregado. Então, eu precisava escrever uma regra de CSS ou include uma folha, como a página carregada.

Obviamente, isso não funcionará em XHTML, mas como o XHTML parece ser uma espécie de dead duck (e renderizado como uma tag soup no IE) pode valer a pena reavaliar sua escolha de DOCTYPE …

Ele quebra páginas usando a renderização de XML (como páginas XHTML).

Melhor : alguns navegadores retornam à renderização HTML e tudo funciona bem.

Provável : algum navegador desativa a function document.write () no modo de renderização XML.

Pior : alguns navegadores irão triggersr um erro XML sempre que usar a function document.write ().

Ele substitui o conteúdo da página, que é o motivo mais óbvio, mas eu não o chamaria de “ruim”.

Simplesmente não tem muito uso, a menos que você esteja criando um documento inteiro usando JavaScript, caso em que você pode começar com document.write.

Mesmo assim, você não está realmente aproveitando o DOM quando usa document.write – você está apenas colocando um blob de texto no documento, então eu diria que é uma forma ruim.

Em cima da minha cabeça:

  1. document.write precisa ser usado no carregamento da página ou no carregamento do corpo. Então, se você quiser usar o script em qualquer outro momento para atualizar o conteúdo da página, document.write é praticamente inútil.

  2. Tecnicamente, document.write só atualizará as páginas HTML, não XHTML / XML. IE parece ser bastante indulgente deste fato, mas outros navegadores não serão.

http://www.w3.org/MarkUp/2004/xhtml-faq#docwrite

O Chrome pode bloquear o document.write que insere um script em certos casos. Quando isso acontece, ele exibe esse aviso no console:

Um script de bloqueio de parser, de origem cruzada, …, é invocado via document.write. Isso pode ser bloqueado pelo navegador se o dispositivo tiver conectividade de rede ruim.

Referências:

Pode-se pensar em document.write () (e .innerHTML) para avaliar uma string de código fonte. Isso pode ser muito útil para muitas aplicações. Por exemplo, se você pegar código HTML como uma string de alguma fonte, é útil apenas “avaliá-lo”.

No contexto do Lisp, a manipulação do DOM seria como manipular uma estrutura de lista, por exemplo, criar a lista (laranja) fazendo:

 (cons 'orange '()) 

E document.write () seria como avaliar uma string, por exemplo, criar uma lista avaliando uma string de código fonte como esta:

 (eval-string "(cons 'orange '())") 

Lisp também tem a habilidade muito útil de criar código usando manipulação de lista (como usar o “estilo DOM” para criar uma tree de análise JS). Isso significa que você pode criar uma estrutura de lista usando o “estilo DOM”, em vez do “estilo de string”, e então executar esse código, por exemplo, assim:

 (eval '(cons 'orange '())) 

Se você implementar ferramentas de codificação, como simples editores ativos, é muito útil ter a capacidade de avaliar rapidamente uma string, por exemplo, usando document.write () ou .innerHTML. Lisp é ideal nesse sentido, mas você pode fazer coisas muito legais também em JS, e muitas pessoas estão fazendo isso, como http://jsbin.com/

  • Um motivo simples pelo qual document.write é uma prática ruim é que você não pode criar um cenário em que não consiga encontrar uma alternativa melhor.
  • Outra razão é que você está lidando com strings ao invés de objects (é muito primitivo).
  • Apenas acrescenta aos documentos.
  • Não tem nada da beleza de, por exemplo, o padrão MVC (Model-View-Controller) .
  • É muito mais poderoso apresentar conteúdo dynamic com ajax + jQuery ou angularJS .

As desvantagens do document.write dependem principalmente desses três fatores:

a) Implementação

O document.write () é usado principalmente para gravar conteúdo na canvas assim que esse conteúdo for necessário. Isso significa que isso acontece em qualquer lugar, seja em um arquivo JavaScript ou dentro de uma tag de script em um arquivo HTML. Com a tag de script sendo colocada em qualquer lugar dentro de tal arquivo HTML, é uma má idéia ter instruções document.write () dentro de blocos de script que são entrelaçados com HTML dentro de uma página web.

b) Renderização

Um código bem projetado, em geral, irá pegar qualquer conteúdo gerado dinamicamente, armazená-lo na memory, continuar manipulando-o enquanto ele passa pelo código antes que ele finalmente seja cuspido na canvas. Portanto, para reiterar o último ponto da seção anterior, a renderização de conteúdo in-loco pode renderizar mais rápido do que outro conteúdo que pode ser invocado, mas pode não estar disponível para outro código que, por sua vez, exige que o conteúdo seja processado. Para resolver este dilema, precisamos nos livrar do document.write () e implementá-lo da maneira correta.

c) Manipulação Impossível

Uma vez que está escrito, acabou e acabou. Não podemos voltar a manipulá-lo sem tocar no DOM.

Baseado em análises feitas pelo Google-Chrome Audit Tools da Dev Tools insira a descrição da imagem aqui

Eu acho que o maior problema é que quaisquer elementos escritos via document.write são adicionados ao final dos elementos da página. Isso raramente é o efeito desejado com layouts de página modernos e AJAX. (você deve ter em mente que os elementos no DOM são temporais e quando o script é executado podem afetar seu comportamento).

É muito melhor definir um elemento de espaço reservado na página e manipular seu innerHTML.