Introdução ao DOM - Document Object Model

O Document Object Model ou simplesmente DOM é utilizado pelo navegador Web para representar a sua página Web. Quando altera-se esse modelo com o uso do Javascript altera-se também a página Web. É muito mais fácil trabalhar com DOM do que diretamente com código HTML ou CSS.

Um dos grandes responsáveis por isso tudo é o objeto document que é responsável por conceder ao código Javascript todo o acesso a árvore DOM do navegador Web. Portanto, qualquer coisa criado pelo navegador Web no modelo da página Web poderá ser acessado através do objeto Javascript document.

Usa-se o DOM principalmente para atualizar uma página Web (DOM é bastante utilizado com Ajax) ou quando se quer construir uma interface de usuário avançada. Com o DOM pode-se mover itens dentro de uma página ou criar efeitos CSS bastante interessantes sem precisar nem mesmo recarregar a página.

Objeto Document

Através do objeto document pode-se ter acesso a um grande número de propriedades. Segue abaixo algumas propriedades que podem ser utilizadas com o objeto document:

Propriedade Descrição
documentElement Captura o elemento raiz <html> de um documento HTML.
getElementById Busca um elemento da página Web com o uso do atributo id do elemento.
createElement Cria um nodo elemento na página.
createAttribute Cria um nodo atributo na página.
createTextNode Cria um nodo texto na página.
getElementsByTagName Retorna um array dos elementos com o mesmo nome.
appendChild Insere um novo elemento filho.
removeChild Remove um elemento filho.
parentNode Retorna o nodo pai de um nodo.

Segue abaixo um exemplo de uma árvore DOM de uma página Web. Pode-se notar que todos os elementos da página Web estão disponíveis para serem manipulados.

Exemplo de uma árvore DOM de uma página Web
Figura 1. Exemplo de uma árvore DOM de uma página Web

Todas as páginas Web são de alguma forma uma árvore. Isso se deve ao fato de podermos ver uma página Web como uma árvore, com uma raiz como o elemento HTML e os seus filhos como o HEAD e o BODY que por sua também possuem elementos filhos e assim sucessivamente. Os elementos que não possuem filhos são chamados de nós folhas, como por exemplo os elementos TITLE, STYLE, SCRIPT, LI, H1, P, TD demonstrados acima. Note que Text é um texto que está dentro de um elemento. O nó <TD> por exemplo também é considerado um nó, mas um nó de tipo diferente (tipo texto).

Essa estrutura de árvore é a forma que o navegador organiza as marcações do HTML, é dessa forma que o navegador Web enxerga um documento HTML. A leitura da árvore se dá sempre da esquerda para a direita, assim teremos a página Web original.

Uma boa prática para evitar que os navegadores apresentem a pagina Web de formas diferentes é sempre escrever HTML padrão, se possível sempre validando a página HTML. Fechar os elementos corretamente, utilizar tags atuais evitando as tags desatualizadas ajudam os navegadores a exibirem uma página Web de maneira correta.

As especificações do Object Document Model são publicadas pela World Wide Web Consortium (W3C). Portanto, o DOM é um padrão de fato.

Percorrendo Árvores DOM

Como visto anteriormente tem-se uma árvore na qual podemos percorrer-la utilizando a variável document no código Javascript. Como cada nó tem um pai e a maioria tem um nó filho, pode-se percorrer essa árvores DOM subindo e descendo nela usando essas conexões. Lembrando que tudo que há na árvore DOM é um nó e nisso incluímos também os textos, elementos, atributos e inclusive os comentários. Todos eles são agrupados pelo DOM em um objeto Node. Elementos e textos são tipos especiais de nós mas também são nós. Quando tivermos um nó podemos capturar seu nome com nodeName e seu valor com nodeValue. Porém, precisa-se tomar cuidado pois eles podem retornar um valor nulo como, por exemplo, no caso de acessarmos um nó de Elemento como o div que possui um nome mas não possui valor. Um nó de Texto por sua vez possui um valor mas não possui um nome.

É importante diferenciar o que é um nó de Texto e um nó de Elemento. Por exemplo, toma-se o HTML abaixo:

<html>
	<head>
		<title>
			Teste de Árvore DOM
		</title>
	</head>

<body>
	<p>Você conhece sobre árvores DOM? Se não 
	conhece aprenda em 
	<a href=“www.devmedia.com.br”>www.devmedia.com.br</a> 
	e seja o mais novo entendido sobre o assunto.</p>
</body>
</html>
Listagem 1. Percorrendo árvores

Nesse exemplo tem-se como exemplo de tipo de nós Elemento o div, p e o a. Seus nodeName seriam div, p e a respectivamente. Esses nós de Elemento teriam como nodeValue null/undefined. Os elementos de Texto teríamos por exemplo o “Você conhece sobre árvores DOM? Se não conhece aprenda em” com o nodeName nulo e o seu nodeValue “Você conhece sobre árvores DOM? Se não conhece aprenda em”. No exemplo anterior existem outros elementos de Texto também como o filho de a.

Cada tipo diferente desses nós tem suas próprias propriedades exclusivas. Como exemplo o nó de Elemento tem um método getAttribute() e um setAttribute(), isso porque somente nós Elementos podem ter atributos. No entanto, os nós capturam funcionalidades que são compartilhadas por todos os nós, tantos nós Elementos quanto os nós Texto, como as propriedades parent e childNodes.

Para saber com que tipo de nó estamos lidando pode-se usar a propriedade do nó nodeType que retorna um número e esse número é mapeado para um valor armazenado na classe Node. Há um valor para cada tipo de nó.

Por exemplo, para verificar se um nó é do tipo Elemento ou do tipo Texto poderia-se usar o Java script abaixo:

if (algumNodo.nodeType == Node.ELEMENT_NODE) {
	//código aqui
} else {
	if (algumNodo.nodeType == Node.TEXT_NODE) {
		//código aqui
	}
}
Listagem 2. Verificando o tipo do nó

Cuidado com este código, pois alguns browsers podem não suportar o Node. No entanto, para saber tem-se que a constante 1 é o nó Elemento e a constante 3 é o nó Texto.

Vamos brincar um pouco com o acesso aos nós de Texto e nós de Elementos imprimindo seus valores e nomes além de acessar os seus filhos.

<html>
	<head>
		<script language="javascript">
			function testandoArvoreDOM() {
				var element = document.documentElement.lastChild;
				alert("Eu sou o nodo" + element.nodeName);

				var outroElemento = document.getElementsByTagName('h1')[0];
				alert("Eu sou o nodo " + outroElemento.nodeValue);

				var filho = outroElemento.firstChild;
				alert("Eu sou o nodo " + filho.nodeValue);
			}
		</script>

		<title>
			Teste de Árvore DOM
		</title>
	</head>

<body>
	<h1>Teste de Título</h1>
	<p>
		Você conhece sobre árvores DOM? Se não conhece aprenda em 
		<a href=“www.devmedia.com.br”>www.devmedia.com.br</a> 
		e seja o mais novo entendido sobre o assunto.
	</p>
	<span onclick="testandoArvoreDOM();">Clique aqui para Testar o Acesso a Árvore DOM</span>
  </body>

</html>
Listagem 3. Imprimindo valores

Clique no texto ao final da página e veja a execução desse exemplo. Note que quando tentamos acessar o nodeValue do elemento <h1> que é um nó do tipo Elemento recebemos um null na tela, isso se deve pelo fato de <h1> não ter um valor para esta propriedade. Seu filho na árvore é um nó de Texto que possui um valor que é impresso na tela. O primeiro comando do Javascript “document.documentElement.lastChild” busca o último nó filho do <HTML>, o primeiro é o <HEAD> e o último é o <BODY>.

Outros Exemplos

Abaixo iremos ver alguns exemplos de uso de DOM com uma outra visão. O exemplo abaixo irá mostrar uma notificação no navegador do usuário após cinco segundos.


<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
  <title>Notifier</title>
  <script>

  function notify(text){
    document.getElementById('msg').innerHTML+='<p>'+text+'</p>'
    titleFlick()
  }

  function titleFlick(){
    if(document.hasFocus()){
      document.title='Notifier'
      return
    }
    document.title=document.title=='Notifier'?'* Notifier':'Notifier'
    setTimeout('titleFlick()',500)
  }

  </script>
</head>

<body>
  <input type="button" id="notify" value="Notify in 5 seconds" 
  onclick="notify('Will notify in 5 seconds...');setTimeout('notify(\'Event shoot!\')',5000)" />
  <div id="msg"></div>
</body>

</html>
Listagem 4. Enviando notificação para o navegador do usuário

Caso você queira criar um exemplo de tabelas zebradas usando DOM, você pode fazer facilmente usando o código abaixo.


<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<title>Zebra</title>
<style>
  .zebraon{background:silver}
</style>
<script>
window.onload=function(){
  var zebrar=document.querySelectorAll('.zebra tbody tr')
  for(var i=0;i<zebrar.length;i+=2)
    zebrar[i].className='zebraon'
}
</script>
</head>

<body>
<table class="zebra">
  <thead><tr>
      <th>Vendedor</th> <th>Total</th>
    </tr></thead>
  <tbody><tr>
      <td>Manoel</td>   <td>12.300,00</td>
    </tr><tr>
      <td>Joaquim</td>  <td>21.300,00</td>
    </tr><tr>
      <td>Maria</td>    <td>13.200,00</td>
    </tr><tr>
      <td>Marta</td>    <td>32.100,00</td>
    </tr><tr>
      <td>Antonio</td>  <td>23.100,00</td>
    </tr><tr>
      <td>Pedro</td>    <td>31.200,00</td>
    </tr></tbody>
</table>
</body>
</html>
Listagem 5. Criando tabela zebrada com DOM

Conclusões

Neste artigo vimos o que é o DOM, por que o DOM é utilizado pelos navegadores e como ele é utilizado. Também vimos como o navegador enxerga um documento HTML criando uma árvore DOM para organizar as marcações HTML e como podemos percorrer essa árvore.

Pode-se ver a importância de entendermos esse importante elemento que é muito utilizado para criar páginas complexas e dinâmicas para a Web. Utilizando o DOM suas páginas ficarão mais ricas, dinâmicas e inteligentes.

Bibliografia:

Brett McLaughlin. Head Rush Ajax. O‘Reilly, 2006. DOM, W3C.