ruf space, techblog sobre webstandards e cotidiano web.
10/01, 2006 17:53 por Fellipe
Usar Javascript para manipular DOM torna-se uma tarefa muito interessante após um tempinho de experiência. Para continuar com o laboratório de DOM, fiz um pequeno script que lê o conteúdo de um documento HTML (ou XML) e identifica seu título principal (H1) e subtítulos (H2) de modo que possamos criar uma lista dinâmica (via JS) de links para os subtítulos abaixo do título principal e links para o título principal abaixo de todos os subtítulos.
Para visualizar o script em ação, veja o exemplo aqui.
Observe o exemplo e em seguida abra seu código fonte. Dentro do seção <body> não existe lista (<ul>) ou âncora (<a>) alguma, tudo é construído dinamicamente através da função que chamei de dynamicHeaderList(), localizado no topo do código.
Esta idéia, em particular, começou a partir de um objetivo incomum: fazer uma versão de brincadeira para este blog aparecer em uma tela de celular. No meio da idéia, resolvi dissecar um artigo que fiz tempos atrás sobre blockquote chamado DOM na prática e aproveitar algumas funcionabilidades que aquele script tinha.
Primeiro, a função principal, chamada dynamicHeaderList(). Esta função tem como propósito ler o documento por inteiro, gerar array dos cabeçalhos e posicionar os itens criados…
[code lang=”javascript”]
function dynamicHeaderList() {
if (!document.getElementsByTagName || !document.createElement || !document.appendChild) return;
var father = document.getElementsByTagName(”h1″);
father[0].setAttribute(”id”, geraHeaderId(father[0].firstChild.nodeValue));
var headers = document.getElementsByTagName(”h2″);
var buildList = document.createElement(”ul”);
for (var i=0; i < headers.length; i++) {
headers[i].setAttribute("id", geraHeaderId(headers[i].firstChild.nodeValue));
var listItem = document.createElement("li");
var listLink = document.createElement("a");
listLink.setAttribute("href", "#" + headers[i].getAttribute("id"));
listLink.appendChild(document.createTextNode(headers[i].firstChild.nodeValue));
listItem.appendChild(listLink);
buildList.appendChild(listItem);
var link = document.createElement("a");
link.setAttribute("title","Go to TOP");
link.setAttribute("href","#"+father[0].getAttribute("id"));
link.appendChild(document.createTextNode("Top"));
var para = document.createElement("p");
para.appendChild(link);
para.className = "anchor";
headers[i].parentNode.insertBefore(para, headers[i].nextSibling);
}
father[0].parentNode.insertBefore(buildList, father[0].nextSibling);
}
[/code]
H1.father = document.getElementsByTagName("h1"); e como ele é virgem de identificação, ou seja, não tem um id, precisamos usar o método getElementsByTagName e presumir que ele seja o primeiro item do array de elementos H1, denominado posteriormente por father[0].
id próprio, criei outra pequena função chamada geraHeaderId(), ainda tosca, que gera um id a partir do próprio conteúdo escrito no título principal. Em uma tacada só, gero o tal id e associo como atributo do nosso título principal, através do método setAttribute.father[0].setAttribute("id", geraHeaderId(father[0].firstChild.nodeValue));
var headers = document.getElementsByTagName("h2"); Tenho outro objetivo para eles…
buildListvar buildList = document.createElement("ul"); mas ainda não faço nada com ele.
H2 gerada em passo anterior.for (var i=0; i < headers.length; i++)
id para cada H2 diferente, enquanto vou navegando na coleção.headers[i].setAttribute("id", geraHeaderId(headers[i].firstChild.nodeValue));
var listItem = document.createElement("li");
var listLink = document.createElement("a"); um li (ou list item) e um a (ou anchor), nessa seqüência.
listItem adiciono o atributo href e associo o valor referente ao id gerado para o mesmo headers[i] na primeira linha deste loop, criando assim a primeira âncora dinâmica.listLink.setAttribute("href", "#" + headers[i].getAttribute("id"));
createTextNode é associado automaticamente um texto com o valor do H2 em questão (headers[i]) ao listLink.listLink.appendChild(document.createTextNode(headers[i].firstChild.nodeValue));
listLink é colocado como filho de listItem, e listItem como filho de buildList.listItem.appendChild(listLink);
buildList.appendChild(listItem); Tudo isso serve para formar a nossa lista de links (ul) conforme o loop for identificando e navegando por novos subtítulos (H2).
link. Adicionamos o atributo title com o valor Go to TOP no objeto link. Adicionamos outro atributo, o href, cujo valor é o id do título principal. Criamos novamente uma ramificação de texto dentro do nosso link, deixando escrito top para o usuário. Criamos outro elemento, desta vez um parágrafo, e falamos que o nosso objeto link é filho do nosso parágrafo chamado para. Por fim, falamos que o objeto para pertence a classe (de CSS) chamada anchor.var link = document.createElement("a");
link.setAttribute("title","Go to TOP");
link.setAttribute("href","#"+father[0].getAttribute("id"));
link.appendChild(document.createTextNode("Top"));
var para = document.createElement("p");
para.appendChild(link);
para.className = "anchor";
para) que contém o link para o topo logo depois de cada subtítulo da página em questão.headers[i].parentNode.insertBefore(para, headers[i].nextSibling); E repetimos o loop, caso a condição ainda seja verdadeira, ou seja, caso ainda existam H2 na página.
H2) tenham acabado, então o loop termina e finalmente podemos chegar ao último passo:father[0].parentNode.insertBefore(buildList, father[0].nextSibling); Inserimos o buildList, agora completo, logo abaixo do título principal (H1). Veja a finalização aqui e observe o fonte dentro do body.
O geraHeaderId() recebe um parâmetro, o headerNode. Este parâmetro deve ser uma string nua e crua, pois essa função divide esta string em vários pedaços (delimitados por seus espaços em branco) e faz junção de suas iniciais… mais ou menos para transformar isso: Título de alguma notícia, nisso: tdan. Útil para gerar ids sempre que necessário.
Apesar deste artigo estar grande e até bastante confuso para quem não sabe do que se trata, espero que possa ajudar bastante quem está se iniciando no mundo de DOM.
Para estudar DOM recomendo muitas visitas ao Google, DevGuru e W3 Schools. Lá, além de um índice completo, existem exemplos muito bons. Não posso esquecer de citar a fonte oficial, o DOM no W3C. Apesar de achar a fonte oficial um paraíso, ele ainda parece muito restrito aos que estão extremamente ligados com os padrões promovidos por eles próprios, e é justamente por isso que eu julgo necessário a existência de blogs que façam a digestão daquele conteúdo! Salvem os techblogs.
Este artigo foi publicado Tuesday, 10 de January de 2006 às 17:53 e foi categorizado como Cookbook, DOM Lab.
Você pode acompanhar os comentários deste post assinando o comment RSS (RSS 2.0 [?]).
Você também pode comentar ou atrelar um trackback [?] daqui no seu site.
11 de January, 2006 às 11:29
Muito bom, cara
parabéns
11 de January, 2006 às 11:50
daki a pouco o html vai ficar praticamente nulo… hehehehehe… estaria o html entrando em extinção? nem tanto…
muito bom cara, parabéns…
11 de January, 2006 às 22:50
Tá ficando bom hein cara.
O semantic-blog vai ficar show com tuas incríveis técnicas com client-side.
16 de January, 2006 às 00:56
Ufa, cheguei!
E, preciso admitir q vc está de mesmo de parabéns!
Passa lá no OPORTUNIDADE DE NEGÓCIOS BRASIL, vc ñ vai precisar de tanta carona
[]s
16 de January, 2006 às 10:17
Muitissímo bem escrito e explicado até msm para quem não teve contato com DOM. Parabéns!
Bjin