jQuery – width de elemento hidden

O jQuery em sua versão 1.4.3 (já leram sobre a jQuery 1.5 que acabou de sair do forno?) tem um bug que impossibilita o uso do .width em elementos que não estão v isíveis na tela (com o uso do display: none), o retorno sempre é 0 para a largura desses elementos.

Segundo o  bug report foi corrigido na versão 1.4.4 (em um dos projetos que estou trabalhando a versão do jQuery era a 1.4.4 e o bug estava presente – como o projeto já estava em fase final achei melhor não alterar a versão da biblioteca e utilizar uma correção quando necessário).

Para quem está em situação parecida, segue um pequeno hack que manipula o CSS do elemento, pega o width e depois desfaz a alteração do CSS.

Usando o .width em elementos invisíveis

            $(this).css({ position: 'absolute', display: 'block' });
            var elemWidth = $(this).width();
            $(this).css({ position: '', display: 'none' });

O que o hack faz é deixar o elemento com display block e position absolute (assim o jQuery não se perde na hora de calcular a largura do elemento), feito isso você pode usar o .width e voltar os valores do position e display do elemento para como estavam antes.

Já passaram por este problema? Como resolveram (ou resolveriam)?

Verifica se string é número no javascript

Já escrevi sobre o typeof do javascript, que retorna o tipo de um objeto no javascript – mas quando estava desenvolvendo algumas coisas do Eu Compraria! Shop eu tinha a seguinte situação: um post por ajax executava uma tarefa, em caso de erro retornaria a mensagem do erro (que poderia variar, de acordo com o erro) em caso de sucesso retornava um ID referente a operação, que eu usaria a partir dali.

Poderia utilizar json para receber um parâmetro success e os outros parâmetros e fazer a verificação do success, mas neste caso optei por algo diferente: verificar se o retorno era numérico (o ID) e prosseguir com o a função, caso contrário seria a mensagem de erro que era exibida para o usuário.

No meu exemplo a data retornada pelo post sempre será uma string (mesmo quando é um ID), portanto o uso do typeof(data) é inútil. Neste caso eu preciso verificar quando uma string é numérica.

 

Verificando se uma string é numérica

A função abaixo testa com expressão regular a string passada como parâmetro e retorna true em caso positivo (string é um número) ou false.

function isNumeric(str)
{
  var er = /^[0-9]+$/;
  return (er.test(str));
}

Update com a sugestão do Aurélio, agora o return é o próprio resultado do teste da regex, sem necessidade do true/false como retorno. Obrigado Aurélio!

Mais uma vez uma expressão regular facilitando nossa vida! 🙂

Verificando o tipo de um elemento no javascript

Estava com problema entre a comunicação de dois serviços diferentes feito pela parte de front-end através do javascript.

Uma requisição ajax para o serviço retornava um array de objetos que a interface deveria percorrer e montar um html como resposta. O problema é que algumas vezes este array continha além dos objetos esperados alguma função de callback ou retorno indefinido (undfined) no array.

Para fazer o tratamento deste erro eu precisaria saber qual é o tipo do objeto retornado e ignorar qualquer um que não fosse "object".

Javascript typeof

O comando typeof do javascript retorna qual é o tipo do objeto em questão, os retornos dessa função podem ser:

  • number
  • string
  • boolean
  • object
  • function
  • undefined

 

Exemplo de uso:

if(typeof(myObj) == "object"){
   alert("myObj é um objeto, pode prosseguir");
}else{
   alert("Não é um objeto, ignore");
}

 

Curiosidades

A função typeof sempre retorna uma string (com os valores da lista lé de cima), então typeof(typeof(x)) sempre irá retornar string, não importa se x é um array, string, int ou função.

Um array é considerado um object, mas com a função abaixo (case sensitive, criamos a função typeOf) retorna os tipos padrões mais o array.

function typeOf(obj) {
  if ( typeof(obj) == "object" )
    if (obj.length)
      return "array";
    else
      return "object";
    } else
  return typeof(obj);
}

 

Função bem simples e ótima para previnir e tratar erros, dúvidas e sugestões nos comentários!

HTML5 Selector API – querySelector querySelectorAll

 Quem acompanha O Desenvolvedor já deve ter percebido que eu sou um grande fã do framework jQuery, utilizo-o diariamente no trabalho e nos projetos pessoais.

Desenvolver utilizando jQuery é extremamente produtivo e fácil, visto o sucesso deste framework a W3C resolveu documentar oficialmente seletores no DOM de forma mais fácil: o  querySelector e querySelectorAll.

querySelector e querySelectorAll

O querySelector é uma API de seleção de elementos do DOM que está disponível diretamente no document, isso facilita os seletores tornando-os muito próximos da seleção do jQuery (a W3C assumiu que os seletores vieram da idéia do jQuery, que na verdade é uma biblioteca separada, chamada Sizzle).

A função é bastante simples e o seletor pode ser de classe (exatamente como no jQuery .nome-da-classe ou de elemento, por exemplo p). O resultado do querySelectAll é uma lista com os elementos que casam com o seu seletor e o do querySelector é apenas o primeiro elemento que casar com a seleção passada.

Exemplo

<style>
.zebraon{background:silver}
</style>
<script>
function zebrado(selector){
var zebrar=document.querySelectorAll(selector);
for(var i=0;i<zebrar.length;i+=2)
zebrar[i].className="zebraon"
}


window.onload=function(){
zebrado("p");
zebrado(".zebra tbody tr");
}
</script>

Fiz um teste criando uma função para "zebrar" qualquer elemento da página (tabelas, por exemplo), no exemplo abaixo zebrei todos os parágrafos da página e as linhas da tabela com a classe zebrado. Para isso criei uma função que recebe como parâmetro a seleção, faz a busca usando o querySelectorAll e adiciona a classe "zebraon" que criei.

 

Um exemplo simples mas que mostra um bom amadurecimento na parte de seletores DOM! Antes de levantar qualquer debate – acho que isso não vai acabar com o uso de frameworks, mas provavelmente vai melhorar a performance das bibliotecas como jQuery já que a seleção será nativa, reduzindo parte da magia negra usada atualmente para isso.

E aí, o que acharam?

ParseInt em Javascript

Pouco depois de aprender arredondamento de números com o PHP eu estava desenvolvendo um código em javascript que recebia algumas informações numéricas e precisava arredondar o número que vinha, a fim de comparar com outro número inteiro.

Usando o parseInt eu percebi umas "reações estranhas" quando eu passava uma string que tivesse zero a esquerda, por exemplo "0x" não retornava X como int, retornava um número estranho.

Fui pesquisar sobre o assunto e abaixo explico o motivo desse retorno estranho…

parseInt

Na documentação do javascript a sintaxe da função é a seguinte:

parseInt(string, radix)

O parâmetro "string" é obrigatório é a string que será convertida para int, o parâmetro radix é opcional – aí começa o problema. Quando este parâmetro não é passado o script vai deduzir qual é o tipo da string passada e transformará ela em int.

Quando o número a ser convertido começa com 0 o script utiliza a conversão para octal, e não decimal. O radix que deve ser passado quando quiser forçar o uso do sistema octal é 8.

Quando o número a ser convertido começa com 0x (exemplo: 0xF) é utilizado o sistema hexadecimal para a conversão. O radix que deve ser passado quando você quiser forçar o uso do sistema hexadecimal é 16.

Nos casos restantes a conversão será feita utilizando o sistema decimal, para forçar o uso do sistema decimal o radix a ser passado é 10.

 

Solução

Se você quer converter o número para int utilizando o sistema decimal sempre passe o segundo parâmetro (radix) como 10, esta é uma boa prática que poderá fazer você economizar tempo tentando descobri porque em alguns casos específicos os cálculos do seu script não saem como o esperado…

Dúvidas e sugestões nos comentários! 🙂