You are currently browsing the category archive for the 'Javascript' category.

A dica é realmente interessante e já me ajudou em outros momentos. Existem momentos que vocês simplesmente deseja fazer aquela “alteração de estilo” no site sem ter que fazer aquele famigerado reload da página. Então, como fazer isso sem usar AJAX?

Pode parecer simples… e é! Basicamente basta chamar a função loadCSS descrita abaixo. A função se baseia apenas no bom e velho DOM e nada mais.

function loadCSS(url) {
    var lnk = document.createElement(’link’);
    lnk.setAttribute(’type’, “text/css” );
    lnk.setAttribute(’rel’, “stylesheet” );
    lnk.setAttribute(’href’, url );
    document.getElementsByTagName(”head”).item(0).appendChild(lnk);
}

NOTA: Só testei no IE 7 e no Firefox 2. Se alguém fizer testes em outros browsers e também funcionar avise e comente.

Palavras-chave: DEFER, onLoad, body, carregamento

O problema é clássico. Você tem uma função/método e deseja que ele seja chamado apenas após o carregamento da página pois esse script interage com algum elemento da página que precisa estar completamente renderizado para poder ser manipulado. Vejamos o exemplo a seguir que muda um objeto do tipo input text para apenas leitura:

<html>
<head>
<script type="text/javascript">
function setDisabled() {
  document.getElementById("foo").disabled = true;
}
// Chamada da função
setDisabled();
</script>
</head>
  <body>
    <form method="post">
      <input type="text" name="foo" id="foo" size="20">
      <input type="submit">
    </form>
  </body>
</html>

Inicialmente esse exemplo deveria ser o suficiente para funcionar. Contudo, não podemos considerar que toda a página será carregada de uma única vez. Caso isso aconteça, quando a função for chamada campo o input pode não ter sido carregado. Resultado: você terá um erro de script.

Existem várias saídas para esse tipo de situação. A mais conhecida é incluir a chamada da função pelo método onLoad da tag body ao invés de executá-lo dentro do bloco <script>:

<body onLoad="setDisabled()">

Mas pode não ser suficiente caso você tenha muitos mais funções a serem chamadas. Outra saída seria incluir o bloco <script> no final do código, mas isso foge um pouco do padrão do W3C de incluir todos os <scripts> entre as tags <head>. A saída para esse problema é a utilização de um atributo pouco conhecido da tag <script>, o DEFER.

O DEFER indica que o bloco script só será carregado após todo o carregamento da página. Dessa forma, para que o primeiro exemplo apresentado funcione bastaria alterá-lo para incluir o atributo:

<script type="text/javascript" DEFER="DEFER">
function setDisabled() {
  document.getElementById("foo").disabled = true;
}

// Chamada da função
setDisabled();
</script>

Palavras-chave: DOM, childnode, removechild, excluir itens

Quando começamos a trabalhar com telas javascript, especialmente quando o assunto tem a ver com Ajax e coisas parecidas, é praticamente inevitável o desejo de tornar aquelas páginas HTML estáticas em algo mais interativo, tal como uma aplicação Desktop, sem aquele eventual “reload”. Nesses casos nada melhor que a combinação DOM + Javascript.

Uma caso bem típico de páginas dinâmicas é atualizar uma coleção qualquer, removendo os itens existentes e incluindo novos.

...

<ul id="Foo">
  <li>um</li>
  <li>dois</li>
  <li>tres</li>
  <li>quatro</li>
  <li>cinco</li>
</ul>

<button onclick="recarrega()">recarrega</button>

...

O trecho acima é uma lista de itens de variando de “um” até “cinco”. Neste exemplo fazemos uso de uma lista comum (tag UL), mas poderíamos fazer o mesmo com qualquer outro tipo de elemento DOM.

Ao final existe um botão que chama uma função javascript chamada recarrega(). Vamos dar uma olhada nela:

function recarrega() {
  var p = document.getElementById('Foo');
  var filhos = p.childNodes;
  for( i = filhos.length - 1; i >= 0; i-- ) {
    if( filhos[i].tagName == 'LI' ) {
      p.removeChild( filhos[i] );
    }
  }

  var li = document.createElement('li');
  li.innerHTML = 'seis';
  p.appendChild(li);

  var li = document.createElement('li');
  li.innerHTML = 'sete';
  p.appendChild(li);
}

A função não tem segredo algum. Após recuperar o elemento “pai” da lista (identificado como Foo), buscamos todos os nós abaixo dele, que no nosso caso são os itens da lista (LI), através do atributo childNodes. Esse atributo é uma lista comum e pode ser acessada como se fosse um array.

Dentro do for tomamos cuidado de excluir apenas os elementos de tagName LI. Observe que os itens são recuperados do último para o primeiro. Naturalmente é neste ponto que geralmente as pessoas se perdem.

Se ao invés de iterar sobre a lista na ordem inversa tivéssemos ido em ordem crescente, ao excluir um elemento em uma dada posição, o elemento seguinte assumiria essa posição. No loop seguinte o contador i teria sido incrementado e buscaria o elemento nessa posição, que agora ocupa a posição do item excluído anteriormente.

Quando isso ocorre ou o script pula um elemento a ser excluído ou tenta excluir um item que não existe na lista gerando uma exceção.

Palavras-chave: Javascript, HTML, XHTML, SVG, XML, CDATA, válido, validator

Você mudou suas páginas de HTML para XHTML e agora elas não validam mais por causa do Javascript. O que acontece?

No HTML, todo o conteúdo da tag <script> é considerado texto normal (CDATA - Character Data) e é simplesmente ignorado pelo parser HTML. Nenhum < ou & que for usado no Javascript vai ser considerado início de tag ou de entidade.

Já no XHTML e outros formatos derivados do XML como o SVG, a tag <script> é uma tag como outra qualquer, que pode ter outras tags dentro dela. Seu conteúdo é analisado pelo parser. Por isso qualquer < encontrado no Javascript vai ser interpretado como início de tag e vai dar erro.

Tudo o que você precisa fazer, é dizer ao parser que o seu Javascript é CDATA, ou seja, texto normal que não deve ser interpretado como XML. Tem uma tag especial para isso:

<![CDATA[  ...  ]]>

Tudo o que estiver dentro dessa tag feia vai ser protegido. Então basta colocar todo seu código dentro dela:

<script type="text/javascript">
// <![CDATA[

alert("Funcionou!")

// ]]>
</script>

Note que as tags de início e fim do CDATA foram comentadas, assim evita-se o problema de o Javascript tentar interpretá-las também.

Palavras-chave: DOM, eventos, target

Existem diversas maneiras de registrar um evento. Na forma tradicional, a função deve ter como único parâmetro uma referência ao evento que a invocou. Então, se a função não recebe nada além desse parâmetro, como descobrir quem emitiu o evento?

Imagine que você possua três DIVs e deseje fazer alguma coisa com eles. Vamos associar o evento onClick a uma função chamada mudacor.

...
<div id="um">UM</div>
<div id="dois">DOIS</div>
<div id="tres">TRES</div>

<script type="text/javascript">
document.getElementById('um').onclick = mudacor;
document.getElementById('dois').onclick = mudacor;
document.getElementById('tres').onclick = mudacor;
</script>
...

O padrão W3C define que eventos possuem o atributo target, responsável por indicar a origem do evento. Contudo, o Internet Explorer ignora esse padrão e diz que deve ser usado srcElement. De qualquer maneira, o comportamento é o mesmo. Vejamos como implementar essa função.

O Internet Explorer ignora o parâmetro passado à função. Segundo ele, os eventos pertencem ao objeto window. Assim, antes de recuperar o atributo target (ou srcElement) é preciso verificar se o evento realmente existe.

function mudacor(e) {
    var emissor;
    if(!e) var e = window.event;
    if (e.target) emissor = e.target;
    else if (e.srcElement) emissor = e.srcElement;

    emissor.style.backgroundColor = '#00FF00';
}

Palavras-chave: array, foreach, undefined

Arrays em javascript tem um comportamento curioso. Você pode instanciá-los com um tamanho pré-definido ou incrementá-los / decrementá-los à medida que achar necessário.

Mas, existe uma situação peculiar. Imagine a seguinte situação:

var a = new Array();
a [3] = 'd';

Ao definir a posição 3 como a letra “d” o javascript criou juntamente todas as três posições que a antecedem (0, 1 e 2). Veja o que acontece quando itera sobre esse array utilizando um for comum:

for( i = 0; i < a.length; i++ ) {
    alert( a[i] );
}

O resultado será três registros “undefined” antes da posição 3. Então, como fazer para recuperar apenas os valores que tiverem tiverem sido definidos? A solução é o que, em outras linguagens, chamamos de foreach. Sua utilização faz uso do operador for de uma maneira diferente:

for( i in a ) {
    alert( a[i] );
}

O foreach em Javascript irá navegar em todos os valores do Array a que não forem undefined e atribuirá em i o índice desses valores no array.

Add to Technorati Favorites

a