Nesta etapa explicaremos como alcançar e manipular os objetos de um documento utilizando as funções do Javascript DOM.
Para desenvolvedores Javascript inexperientes, o HTML é o seu playground.
HTML:
<a href="index.html" onmouseover="image1.src='1on.gif'"
onmouseout="image1.src='1off.gif'">
<img src="1off.gif" name="image1" border="0"
height="150" width="150" alt="home">
</a>Ou se ele é um pouco mais avançado:
HTML:
<a href="index.html" onmouseover="roll('home',1)"
onmouseout="roll('home',0)">
<img src="home.gif" name="home" border="0"
height="150" width="150" alt="home">
</a>
Javascript:
// pre-carregamento da imagem
homeoff = new Image();
homeoff.src = 'home.gif';
homeon = new Image();
homeon.src = 'homeoff.gif';
function roll(imgName,a)
{
imgState=a==0?eval(imgName + 'on.src'):eval(imgName + 'off.src');
document.images[imgName].src = imgState;
}
De qualquer forma, todas as chamadas dos eventos estão no HTML, e se uma função muda de nome, nós somos obrigados a mudar cada documento. Além disso, cada roll-over significa um monte de marcações que serão adicionadas ao peso da página.
Fora! Fora! - Nada de chamada de eventos direto nas tags
Vamos esquecer, por enquanto, que quase todo efeito roll-over, hoje em dia, pode ser feito via CSS, sendo uma opção melhor do que com Javascript. Vamos supor que nós queremos usar a seguinte marcação para criar um roll-over para a imagem:
HTML:
<a href="index.html">
<img src="home.gif" id="home" alt="home">
</a> Agora, como mudar a imagem quando o mouse passar por cima dela?
Escalando os galhos do documento
Cada documento XML (e isso inclui o HTML) é um node tree (a tradução mais adequada desse termo seria "árvore de nós"). Um nó é uma parte dessa árvore (imagine um arquivo ou diretório no Windows Explorer quando você navega pelo seu disco rígido). Um nó pode ser 12 coisas diferentes - mas, para o HTML, somente 3 realmente interessam: Elemento, TextNode e AttributeNode.
Nosso equipamento de escalada
Vamos ver quais funções e atributos que nós podemos usar para escalar a árvore de nós do documento, e como alternar de um elemento para outro.
Funções para alcançar um elemento na pagina
getElementById('elementID') - retorna o elemento que tem a id 'elementID' como um objeto.
getElementsByTagName('tag') - retorna todos os elementos cujo nome seja 'tag' como um vetor.
Mas é claro que você pode misturar e combinar esses dois. Por exemplo:
document.getElementById('navigation').getElementsByTagName('a')[3];
retorna o quarto link dentro do elemento com o id 'navigation'
document.getElementsByTagName('div')[2].getElementsByTagName('p')[0];
retorna o primeiro paragrafo dentro da terceira div do documento.Ferramentas para navegar dentro de certo elemento
- childNodes
- retorna um vetor com todos os nós dentro do atual elemento. Também existem firstChild e lastChild que são apelidos curtos para childNodes[0] e childNodes[this.childNodes.length-1] respectivamente.
- parentNode
- O elemento em que o atual elemento está contido (Ou simplesmente o elemento pai).
- nextSibling
- o próximo elemento no mesmo nível na árvore do documento.
- previousSibling
- o elemento anterior no mesmo nível na árvore do documento.
Todos esses elementos podem ser mesclados de acordo com as suas necessidades.
Javascript:
var other=document.getElementById('nav').childNodes[3].firstChild;
// retorna o primeiro elemento do quarto
// elemento dentro do elemento com o id 'nav'.
var prevlink=o.parentNode.previousSibling.firstChild.childnodes[2];
// retorna o terceiro elemento dentro do primeiro
// elemento do elemento anterior no mesmo nivel do
// elemento pai do elemento o (pode parecer complicado,
// mas leia novamente com atenção e veja como é simples).
Atributos e funções para os elementos
- attributes
- retorna um vetor de todos os atributos deste elemento. Não funciona com o Internet Explorer anteriores a versão 6.
- data
- retorna ou altera os dados textuais de um nó.
- nodeName
- retorna o nome do nó (o nome do elemento HTML).
- nodeType
- retorna o tipo do node; - 1 é um elemento nó, 2 é um atributo e 3 é texto.
- nodeValue
- retorna ou altera o valor do nó. Esse valor é o texto quando o nó é do tipo texto, um atributo quando é do tipo atributo e null se for um outro elemento.
- getAttribute(attribute)
- retorna o valor do atributo 'attribute' .
Javascript:
var other=document.getElementById('nav').firstChild;
if(other.nodeType==3)
{
other.data='newtext';
}
if(other.nodeType==1)
{
other.firstChild.data='newtext';
} Agora, para alcançar a imagem no nosso exemplo, nós podemos usar qualquer um, getElementByTagName ou getElementById.
HTML:
<a href="index.html">
<img src="home.gif" id="home" alt="home">
</a>
Javascript:
function findimg()
{
var image;
image=document.getElementById('home');
if (image)
{
image.style.border='3px dashed #ccc';
}
}
ou:
function findimg()
{
var imgs,i;
imgs=document.getElementsByTagName('img');
for(i in imgs)
{
if(/home.gif/.test(imgs[i].src))
{
imgs[i].style.border='3px dashed #ccc';
}
}
}
Usando o getElementById é muito mais fácil, como nós não temos que ter um loop através de todos os elementos para achar um identificador único. Neste exemplo, nós verificamos se o atributo src da imagem contem 'home.gif'. O modo mais comum é verificar uma classe especial.
HTML:
<a href="index.html">
<img src="home.gif" class="roll" alt="home">
</a>
Javascript:
function findimg()
{
var imgs,i;
imgs=document.getElementsByTagName('img');
for(i in imgs)
{
if(/roll/.test(imgs[i].className))
{
imgs[i].style.border='3px dashed #ccc';
}
}
}
Agora, para adicionar um efeito roll-over, tudo que nós precisamos fazer é adicionar uma função que faz a mudança da origem da imagem, e adicionar os manipuladores de eventos na imagem.
function findimg()
{
var imgs,i;
// loop através de todos os elementos do documento
imgs=document.getElementsByTagName('img');
for(i=0;i<imgs.length;i++)
{
// testa se a classe roll existe
if(/roll/.test(imgs[i].className))
{
// adiciona a função roll na imag
// em quando 'onmouseover' e 'onmouseout'
// levando como argumento a img como objeto
imgs[i].onmouseover=function(){roll(this);};
imgs[i].onmouseout=function(){roll(this);};
}
}
}
function roll(o)
{
var src,ftype,newsrc;
// pega o atributo src da imagem, e descobre a extensão do arquivo
src = o.src;
ftype = src.substring(src.lastIndexOf('.'), src.length);
// verifica se o atributo src já tem '_on' e se tiver apaga ele
if(/_on/.test(src))
{
newsrc = src.replace('_on','');
}
else
{
// senão, adiciona o '_on' no src da imagem
newsrc = src.replace(ftype, '_on'+ftype);
}
o.src=newsrc;
}
window.onload=function(){ findimg(); }
Teste esse exemplo
Muito bom por enquanto. Mas nós esquecemos uma coisa: mesmo sendo meramente um efeito visual, um roll-over deveria funcionar mesmo sem o mouse. Para isto, nós precisamos verificar se o link em volta da imagem está em foco ou não, pois a imagem propriamente dita não é acessível pelo teclado quando está envolvida em um link.
Para fazer isso, nós precisamos pegar o elemento que contém a imagem, nesse caso o link. Faremos usando o comando parentNode. Como isto muda o objeto que vai como parâmetro para a função roll(), nós precisamos encontrar a imagem novamente.
Daqui, nós vamos rodar através dos childNodes do link e descobrir qual element é uma imagem, verificando o nodeType e o nodeName. Isso é necessário pois alguns navegadores vêem o espaço em branco como um nó, enquanto outros não.
function findimg()
{
var imgs,i; // Faz um loop através de todas as imagens
//verificando se alguma delas contém a classe 'roll'
imgs=document.getElementsByTagName('img');
for(i=0;i<imgs.length;i++)
{
if(/roll/.test(imgs[i].className))
{ // adiciona a função roll ao elemento-pai da imagem
imgs[i].parentNode.onmouseover=function(){roll(this); };
imgs[i].parentNode.onmouseout=function(){roll(this);};
imgs[i].parentNode.onfocus=function(){roll(this);};
imgs[i].parentNode.onblur=function(){roll(this);};
}
}
}
function roll(o)
{
var i,isnode,src,ftype,newsrc,nownode;
// loop através de todos os childNodes
for (i=0;i<o.childNodes.length;i++)
{
nownode=o.childNodes[i];
// se o nó é um elementoif the node is an element and
// e é uma IMG, muda a variável e sai do loop
if(nownode.nodeType==1 && /img/i.test(nownode.nodeName))
{
isnode=i;
break;
}
} // verifica o src e faz o roll-over
src = o.childNodes[isnode].src;
ftype = src.substring(src.lastIndexOf('.'), src.length);
if(/_on/.test(src))
{
newsrc = src.replace('_on','');
}
else
{
newsrc = src.replace(ftype, '_on'+ftype);
}
o.childNodes[isnode].src=newsrc;
}
window.onload=function() { findimg(); }
Teste esse exemplo clicando aqui.
Bom pessoal, então é isso, espero que tenha sido útil para vocês. No próximo artigo falaremos sobre como criar e destruir objetos no documento.
Abraços! Até a próxima!














4 Comentários
Qual a sua opinião?