Internet Explorer 8 – beta 2

E foi lançado o beta 2 do Internet Explorer 8 (faça aqui o download).

Além de estar bem mais bonito e fácil de usar, a grande diferença para quem trabalha com web é o suporte dado pelo browser aos padrões web (webstandards) – a Microsoft já tinha feito um bom avanço no IE7, quando comparado ao IE8; mas parece que agora essa preocupação ficou mais forte (será que  apelo da comunidade ajudou nisso?). Inclusive muitas coisas da especificação 3 do CSS estão sendo implementadas (veja aqui a lista de novidades em termos de CSS no IE8).
Okey, muitas coisas desse IE8 não são novidades para quem usa Firefox ou Opera, por exemplo, como um DOM Inspector ou melhor debugger de javascript (coisa que o Firebug faz no FF), a opção de desativar o CSS ou, ainda, um campo para buscar em diferentes serviços (Live Search, Google, Yahoo, etc…) e suporte a microformats (IE´s Web Slices).

 

A cara nova do IE8:


Campo de sugestão de busca


Seleção de compatibilidade (onde você pode ver as páginas rendereizadas em versões antigas do IE)


Bookmarks

 

Vale a pena falar que há uma mudança grande na parte de privacidade: existe uma funcionalidade nova, chamada de private browsing, onde o usuário pode incapacitar o browser de acessar dados (como o histórico, dados de formulário, arquivos temporários, etc…). Com um clique apenas, você pode definir que um site específico não deve ter seus dados gravados, evitando qualquer referência a ele no seu histórico.

Sugiro esse post aqui, bem completinho, sobre as funcionalidades do IE8.

[update]Nesse post aqui no Webinsider, fala-se sobre o impacto do private browsing em termos de métricas[/update]

Protegendo seu e-mail de spammers

Infelizmente muita gente acha que pós venda ou e-mail marketing é simplesmente sair enviando e-mails adoidado para qualquer um que apareça na frente. Isso é spam. Aqui tem algumas dicas sobre como fazer um e-mail markerting eficiente, hoje escrevo para uma dica de como evitar que seu e-mail caia nos bancos de dados de spammers…

Para montar um banco de dados com e-mails os spammers utilizam bots que navegam livremente pela internet, coletando todos os e-mails que  eles conseguem "ler" nas páginas, então quando você coloca seu e-mail em um texto ou um link de mailto ele terá chances (enormes) de parar em algum CD vendido na Santa Efigênia com 2 milhões de e-mails.

 

Como você pode ajudar combater o SPAM?

Aqui vão duas técnicas que não levam tempo nenhum e vão ajudar a reduzir o spam – para você e para todo mundo. Se a maioria dos usuários fizesse isso…

 

Mas você quer facilitar a vida do usuário, divulgar seu e-mail e deixar seu cliente a um clique de escrever um e-mail, certo? O pinceladas da web divulgou uma excelente solução em JQuery (do kevinleary) que pega seu e-mail "camuflado" e torna ele um link quando o usuário acessa a página.

Facilita a vida dos usuários do seu site sem deixar seu e-mail ser lido por bots – a não ser que elex executem o javascript antes de ler a página, claro.

Como proteger o e-mail de spammers?

Antes você precisa ter o JQuery "instalado" no seu site, se você ainda não tem recomendo ler o post do Chris sobre a Google AJAX Libraries API que mantém seu site com sua biblioteca favorita sempre atualizada e sem ter que hospedar arquivo nenhum.

Com o Jquery configurado no site, vamos ao código que faz a mágica acontecer: 

$(document).ready(function(){
	$("a[rel=´email´]").each(function(){
		// Modifica o valor de mailto:
		var mailtoVal = $(this).attr(´href´);
		mailtoVal = mailtoVal.replace("[email]","mailto:");
		mailtoVal = mailtoVal.replace("[at]","@");
		mailtoVal = mailtoVal.replace("[dot]",".");
		// Gera automaticamente a tag title para os usuários
		var mailtoTitle = mailtoVal.replace("mailto:","Email: ");
		$(this).attr(´title´,mailtoTitle);
		// Evento onClick
		$(this).click(function(){
			window.location.href = mailtoHref;
			return false;
		});
	});
});

E para colocar o link protegido é simples, seu e-mail deve ficar assim:

Contato

Simples e eficiente! 😉

Como retirar acentos de um form utilizando javascript?

Já antecipo que estou aprendendo javascript – e evoluíndo bastante com meus estudos para o novo And After, e eis que trabalhando no novo sistema de buscas internos eu queria limpar a acentuação dos formulários de busca sem utilizar server-side, recorri ao Google para aprender o replace em Javascript.

Falhei em um primeiro momento, o replace do javascript faz a substituição apenas uma vez.

Exemplo que não funciona (com replace)

Se você quer retirar os acentos de "É fácil plantar árvores" e usar um replace para substituir "á" por "a" a substituição acontecerá somente no primeiro "á".

Como eu não estou (estava?) familiarizado com javascript, não sabia das manhas. É possível fazer com replace desde que você crie um pequeno loop.

 

Exemplo que funciona (com replace)

No exemplo abaixo eu criei uma função para retirar todos os espaços do valor de um input de texto, o exemplo facilita o entendimento de funciona o replace.

function retiraespaco(x) {
var campo = document.getElementById(x)
novo = novo.replace(" ","-");
campo.value = novo;
}

 

Para retirar todos os espaços eu criei um loop para cada caracter da variável (neste caso o valor do input X). Mas e para retirar todas as possibilidades de acentuação?

Retirando a acentuação de um Input de texto

Você poderia fazer um loop para cada possibilidade, mas seria um trabalhão e o código ficaria grande, recorri novamente ao Google e encontrei em um fórum uma função feita por um tal de Luís, que a seguinte:

function retira_acentos(palavra) {
com_acento = ´áàãâäéèêëíìîïóòõôöúùûüçÁÀÃÂÄÉÈÊËÍÌÎÏÓÒÕÖÔÚÙÛÜÇ´;
sem_acento = ´aaaaaeeeeiiiiooooouuuucAAAAAEEEEIIIIOOOOOUUUUC´;
nova=´´;
for(i=0;i<palavra.length;i++) {
if (com_acento.search(palavra.substr(i,1))>=0) {
nova+=sem_acento.substr(com_acento.search(palavra.substr(i,1)),1);
}
else {
nova+=palavra.substr(i,1);
}
}
return nova;
}

 

Ainda não fiz testes para entender como funciona o search no javascript, mas mesmo sem entender o funcionamento específico de cada linha do código é fácil implementá-lo para uso. No meu caso eu chamei a função para definir o valor de um input enquanto o usuário digita, retirando automaticamente os acentos do formulário de busca, segue o código do formulário

<form class="form_busca" method="get" action="busca.asp" name="busca">
<input type="text" onkeyup="this.value=retira_acentos(this.value);" class="texto_busca" value="BUSCA" id="query" name="query" />
<input align="absmiddle" type="image" src="https://andafter.org/beta/images/botoes/ok.png" name="Buscar" />
</form>

 

Pronto, quando o usuário digitar uma busca automaticamente a função irá retirar os assuntos. Não custa nada chamar a função quando o formulário for enviado, fiz testes e as vezes quando o conteúdo é colado no input os acentos podem "escapar", se chamar a função quando o form for enviado não tem erro! 

Dúvidas, críticas e correções nos comentários! 😉

Classe para gravar e ler cookies – por javascript

Juntando a idéia desse post do @gserrano sobre cookies (em ASP) e esse outro que fiz semana passada sobre orientação a objetos em javascript usando a biblioteca Prototype, tive a idéia de disponibilizar uma classe que fiz certa vez para gravar e ker cookies da máquina do usuário da sua aplicação.
*não vou aqui discutir a segurança e todos os outros pontos relativos ao não-uso de cookies (o qual concordo, mas certas vezes temos que fazer coisas na nossa vida profissional que vão contra nossos conceitos, né? :-/ )

Esse é o código da classe:

Cookie.prototype = {
    //construtor padrão
    initialize: function() {
         
    },
    /*
     * salva cookie no formato {chave}={valor};
     */
    setCookie: function(key, value) {
        var the_cookie = key + "=" + value + ";" ;
        document.cookie = the_cookie;
    },
   
    /*
     * retorna valor do cookie
     */
    getCookie: function (key) {
        var search = key + "="
        var returnvalue = "";
        if (document.cookie.length > 0) {
            offset = document.cookie.indexOf(search)
            if (offset != -1) {
                offset += search.length
                end = document.cookie.indexOf(";", offset);
                if (end == -1)
                    end = document.cookie.length;
                returnvalue=unescape(document.cookie.substring(offset, end))
            }
        }
        return returnvalue;
    }
}

A classe é bem simples: um método setCookie(key, value), o qual recebe uma chave e um valor; a chave é usada como o identificador do cookie, e o valor… bem, ele é o valor propriamente dito.
O outro método é o getCookie(key), que é chamado sendo passada a chave (identificador) referente ao cookie que você quer saber o valor que havia sido gravado.

Vale ressaltar que document.cookie é um comando (pensando se esse é o termo correto) nativo do javascript

Segue abaixo um exemplo funcional (html + javascript) onde há um formulário com dois campos. Ao clicar em salvar, é chamada a função que instancia o objeto Cookie e grava os valores. A outra função instância outro objeto Cookie e lê do cookie do browser do usuário, procurando a chave salva.

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript" src="prototype.js"></script>
<title>Cookie.js</title>
<script type="text/javascript">
var Cookie = Class.create();
Cookie.prototype = {
    //construtor padrão
    initialize: function() {
         
    },
    /*
     * salva cookie no formato {chave}={valor};
     */
    setCookie: function(key, value) {
        var the_cookie = key + "=" + value + ";" ;
        document.cookie = the_cookie;
    },
   
    /*
     * retorna valor do cookie
     */
    getCookie: function (key) {
        var search = key + "="
        var returnvalue = "";
        if (document.cookie.length > 0) {
            offset = document.cookie.indexOf(search)
            if (offset != -1) {
                offset += search.length
                end = document.cookie.indexOf(";", offset);
                if (end == -1)
                    end = document.cookie.length;
                returnvalue=unescape(document.cookie.substring(offset, end))
            }
        }
        return returnvalue;
    }
}
function salvarCookie() {
    var ck = new Cookie();
    ck.setCookie($F(´key´), $F(´value´));
}
function lerCookie() {
    var ck = new Cookie();
    alert(ck.getCookie($F(´key´)));
}
</script>
</head>
<body>
<h1>Cookie.js - teste</h1>
<form name="cookie" action="#">
    <label for="key">chave:</label><input type="text" name="key" id="key" />
    <label for="value">valor:</label><input type="text" name="value" id="value" />
    <a href="#" onclick="salvarCookie(); return false;" title="salvar cookie">salvar cookie</a>
    <a href="#" onclick="lerCookie(); return false;" title="ler cookie">ler cookie</a>
</form>
</body>
</html>
 

Criar classes em javascript – usando a Prototype

Orientação a objetos no javascript? É possível, sim. E muito necessário, ainda mais quando lidamos com projetos de grande porte.
Okey, javascript não é uma linguagem OO (abreviação para orientação a objetos). Nem tudo da orientação a objetos em javascript é possível ser implementada; alguns dos (famosos) paradigmas da OO são impossíveis de serem atingidos por limitações técnicas (por exemplo, não existe o conceito de interface, ou métodos que possam ser sobreescritos). O que não inviabiliza o uso da OO no javascript.

Se você não conhece muito de orientação a objetos, sugiro que você procure na web ou na literatura apropriada os conceitos. Esse post falará sobre o uso da (biblioteca) Prototype na ajuda a implementar a OO.

Quem já implementou do zero uma classe em javascript sabe que a dificuldade não é grande, mas que a sintaxe é meio estranha. Por exemplo, vamos criar uma classe que abstrai um objeto Pessoa:
[update]exemplo retirado do blog do Rodrigo, nesse post aqui[/update]

<script language="javascript">
function Pessoa() {
    var nome;
    var idade;
    var email;
    this.getNome = getNome;
    this.getIdade = getIdade;
    this.getEmail = getEmail;
    this.setNome = setNome;
    this.setIdade = setIdade;
    this.setEmail = setEmail;
    this.mostraValores = mostraValores;
    function getNome() {
        return nome;
    }
    function getIdade() {
        return idade;
    }
    function getEmail() {
        return email;
    }
    function setNome(_nome) {
        nome = _nome;
    }
    function setIdade(_idade) {
        idade = _idade;
    }
    function setEmail(_email) {
        email = _email;
    }
    function mostraValores() {
        return ´Nome: ´ + nome +´ Idade: ´+ idade +´ anos Email: ´+ email;
    }
}
</script>

Para consumir essa classe:

<script language="javascript">
    var pessoa = new Pessoa();
    pessoa.setNome("Rodrigo Lazoti");
    pessoa.setIdade(26);
    pessoa.setEmail("[email protected]");
    alert(pessoa.mostraValores());
</script>

Veja que essa classe mais parece um monte de codificação estruturada agrupada, nem não há um construtor para ela.

Vou direto para a codificação de como ficaria tal classe usando a Prototype:

referenciando a prototype:

<script src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js" type="text/javascript"/>
var Pessoa = Class.create();
Pessoa.prototype = {
    //construtor padrão
    initialize: function(nome, idade, email) {
        this.setNome(nome);
        this.setIdade(idade);
        this.setEmail(email);
    },
    setNome: function(nome) {
        this.nome = nome;
    },
    setIdade: function(idade) {
        this.idade = idade;
    },
    setEmail: function(email) {
        this.email = email;
    },
    mostraValores: function() {
        return "Nome: " + this.nome + " Idade: "+ this.idade + " anos - Email: "+ this.email;
    }
}

Quem está acostumado com OO percebe logo de cara que, dessa forma, a semântica usada é muito mais direta e clara; você sempre se refencia aos atributos da classe usando this, e você sempre é obrigado a ter um método initialize que funciona como o construtor.
Para esclarecer o código, na primeira linha é usado um objeto Class da própria prototype e chama-se o seu método create(); a partir do retorno desse método tem-se um objeto que pode ser trabalhado como uma classe da Prorotype. Vale a pena lembrar que o código usado para consumir a classe pode ser exatamente o mesmo enquanto a interface (resumidamente, assinatura dos métodos) das mesmas forem iguais.

Agora, uma coisa bacana (peguei o exemplo lá na API da Prototype) é como extender uma classe. Imagine que você quer criar a partir da classe Pessoa, uma classe Pirata; digamos que o seu Pirata é do passado, e não tem e-mail. Mas tem um navio.
O primeiro passo é extender a classe Pessoa, da seguinte forma:

var Pirata = Class.create(Pessoa, {});

Vamos ver como ficaria o código para sobreescrever o método setEmail() e adicionar um método novo:

var Pirata = Class.create(Pessoa, {
    // sobreescreve o método que define o e-mail
    setEmail: function() {
        this.email = null;
    },
    //cria um método para salvar o nome do navio dele
    setNavio: function(navio) {
        this.navio = navio;
    }
   
});

Sugiro para quem está afim de estudar mais, primeiro olhar a documentação da API da Prototype e procurar exemplos por ae na net, e depois pegar algo que você já fez e funciona e tentar reescrever, do zero, usando orientação a objetos. É uma curva de aprendizado não muito complexa, mas é uma forma bem diferente de se programar para quem não está acostumado!

[update]e é claro que eu esqueci apenas de de falar que é necessário incluir a biblioteca prototype no seu javascript. Você pode fazer download ou referenciar a mesma que é hospedada pelo Google Code[/update]