Novos projetos: FastChat e Semaphore.js

Sempre curti micro-projetos úteis e reutilizáveis, principalmente widgets.

Bom, para o projeto que estou trabalhando vi a necessidade de dois widgets que imaginei que seria legal de reutilizar, e eis o resultado deles (ainda em desenvolvimento):

Semaphore.js

Um mini widget em javascript que apenas indica o status do servidor através de um semáforo.

Através de um url configurada do widget ele indica se o servidor está online, lento ou offline. É bem útil para aplicações totalmente em ajax, principalmente quando se depende de servidores instáveis ou serviços de terceiros. Permite ainda algumas integrações para cada estado.

Consiste apenas em um pequeno arquivo javascript.

FastChat

Fastchat: chat widget easy to use

Esse é mais legal! É um widget de bate-papo que basta carregar um pequeno javascript sem dependências e está pronto o chat!

Foi feito com um servidor em clojure, usando redis e javascript simples para o widget. Pode-se usar css para customizar a UI padrão, grava um histórico, possui uma “janela” por usuário, lista de onlines e etc.

Bom, é isso, o semaphore.js eu já usei em mais de um projeto e o fastchat ainda está em teste no projeto principal, mas acho que promete bastante.

Javascript DOM não obstrusivo

Volto hoje a escrever sobre javascript . O Ultimo post ja falei um pouco sobre DOM API do javascript e como manipular elementos XHTML em uma pagina. Hoje pretendo focar em boas práticas de como aplicar os recursos de javascript, mantendo o bom código e a acessibilidade.

Algumas premissas devem ser entendidas, sobre as quais não vou prender na explicação. Não se esqueça que o conteúdo vem acima de tudo, então ter um monte de recursos legais não adiante se isso dificultar chegar ao conteúdo, e principalmente o site deve ser perfeitamente navegavel sem javascript. Isso mesmo. Questão de acessibilidade e de SEO.

O JS deve ser usado para facilitar a navegação e oferecer recursos extras, facilidades, e não para SER a navegação em si. Aconselho a primeiro fazer todo o site funcionando normalmente, todo o fluxo de paginas e informações, e depois aplicar o JS onde esse possa ser útil.

Mãos a obra:

Um uso por exemplo de Javascript, ou ajax que seja, em link. Muitos sites hoje utilizam em certo ponto navegação sem reload de pagina, apenas alterando através de JS o conteúdo de uma determinada area do site. O erro é SE o link só funciona dessa forma:

<a href="javascript:func()">

Isso é um erro comum. O correto é que o link funcione e uma pagina abra normalmente com o conteúdo caso o javascript não funcione. Fazendo assim:

<a href="http://pagina.com/"  onclick="return func()" >  ou <a href="http://pagina.com" onclick="func(); return false;" >

O que acontece é que, caso o onclick retorne FALSO, o evento acaba e o link não é acionado. Isso vai acontecer com o JS acionado. Caso o JS não esteja funcionando por algum motivo, o link vai funcionar tradicionalmente. No caso o func() quardadra a função para alterar o conteúdo

Um exemplo de validação automática de formulário, faremos uma função que percorre os campos do fomulario, procurando por aqueles que devem ser validados, e retorna false caso nao valide algum.

<script> 

function valida(form) {
    // deve-se passar qual formulario a valida
    // normalmente this
    for(i=0;(a=form.getElementsByTagName("input")[i]);i++) {
        // Aki fazemos um loop pelos inputs do form
        if(a.getAttribute("valida") == "ok") {
            // se o atribute valida é ok
            if(a.value.lenght <= 1) {
                // Se nao foi preenchido com mais de uma letra
                alert("O campo "+ a.getAttribute("id") +" é obrigatório") ;
                return false;
                // retorna falso, cancelando o envio e terminando a funcao
            }
        }
    }
    return true ;
}

</script> 

E no formulario fazemos assim:

<form action="enviar.php" method="post" name="contanto" onsubmit="return valida(this)" >

Isso que dizer que ao enviar o formulário ele executara a funcao valida. No mesmo caso do link, esta retornando falso o envio é cancelado. Caso nao tenha javascript, o formulario é enviado. Caso os campos estajam preenchidos, o formulario é enviado pois retorna verdadeiro.

Vejam bem, cada caso é um caso. Existe sim por exemplo casos em que se possa fazer uma pagina baseada em JavaScript, se for por exemplo para o painel de controle da empresa, ou para o sistema de gestão. Mas em paginas de INFORMÇÂO, abertas, de CONTEÚDO deve-se pensar duas ou mais vezes antes disso, pois vai dificultar o acesso ao seu conteúdo.

Por hoje é só!

 

Javascript DOM API

Que tal dar uma reforçada nos seus javascript e entender/aprender um recursos bem legais!

Primeiro, isso não é AJAX, AJAX usa esses recursos, isso é apenas JavaScript, apenas não… isso É javascript, e sua poderosa DOM API.

O que é? Bom DOM(Document Object Model) é  uma representação da hierarquia da pagina, e o que faremos aqui é manipular essa estrutura com javascript. Para isso é necessário um documento bem formatado e uma noção de padrões para que tudo funcione como deve, e de preferencia um pouco de orientação a objetos.

Um Exemplo do uso do DOM pode ser visto aqui mesmo no Manifesto, no alternador de css

O Básico

Elemento é uma tag em geral, um objeto no HTML. Vou me referir assim daqui por diante. Vamos a algumas funções básicas:

  • getElementById("id") -> retorna o objeto com o "id" dado. Uso: document.getElementById("id") ;
  • getElementsByTagName("name") -> retorna uma array de elementos "name", esse "name" seria o nome da tag ex. para tag <a href="#"> o "name" é "a".
  • getAttribute("name") -> retorna o valor do attributo "name" de um determinado objeto. Uso: document.getElementById("id").getAttribute("name") ;
  • setAttribute("name","valor") -> Altera o valor do atributo "name" para "valor", uso igual ao acima.
  • removeAttribute("name") -> Remove por completo determinado atributo do elemento.

Sobr pais e filhos

Um pouco mais de definições, um elemento "filho"(child) é aquele que esta contido dentro de um elemento "pai"(parent). No exemplo fica mais claro:

<body> <div id="exemplo">

<p> texto texto texto </p>

<p> texto texto texto </p>  

</div> </body>

 No exemplo acima, a tag <body> é pai da <div id="exemplo">, que por sua vez é pai das tags <p> . No caminho contrario, ambas os <p> são filhos da <div id="exemplo"> que é filha do <body> . E assim continua internamente no documento.

  • createElement("name") -> Cria um elemento chamado "name", que ainda não esta na pagina, uso: document.createElement("name")
  • appendChild("name") -> Adciona um "filho" "name", criado por createElement, a um elemento, uso: document.getElementById("exemplo").appendChild("name") ;
  • createTextNode("texto") -> cira um "nó" de texto, um texto comum digamos.

Isso é apenas o básico, para entendermos melhor vamos usar algum exemplo:

Exemplo:

Bem simples. Supondo que eu tenha uma pagina com o seguinte código assim:

<ul id="primeira_lista" class="alteravel">

    <li class="classe_antiga"> Item 1 </li>

    <li class="classe_antiga"> Item 2 </li>

</ul> 

 E eu quero uma função para adcionar itens a essa lista, de forma a terem um texto especifico e um formatação especifica, vamos a função, porem apenas as listas alteraveis:

function adciona(txt) {

                                                                // passa como paramtro o texto a ser incluso
    var ali = document.createElement("li");         // Criamos um objeto li
    ali.setAttribute("class","novo_item");             // atribumos uma classe a ele
    var texto = document.createTextNode(txt);     // criamos um texto
    ali.appendChild(texto) ;                             // adciomos o texto ao elemento li
   
    listas = document.getElementsByTagName("ul") ; // aqui pegamos todos os elementos ul em uma array
    for(i=0;i<listas.length;i++){
                                                                    // criamos entao um loop atraves dessa array
        classe = listas[i].getAttribute("class");         // recuperamos o valor do atributo classe
        if(classe == "alteravel") {
                                                                    // Caso o valor de classe seja alteravel adcionamos o novo elemento
            listas[i].appendChild(ali);
        }       
    }

 Agora basta chamar a funcao adciona(txt) , sendo txt o texto a ser adcionado, que este sera adciona a todos a lista não ordenadas (ul) que foram da classe "alteravel", e estes novos itens receberao a classe "novo_item".

 Apartir disso basta usar a criatividade e se divertir! Existem ainda muitos outros recursos, uma boa referencia é o post do elcio sobre DHTML

Dúvidas é só se manifestar!

Alternador de Estilos CSS

Um truque interessante que aprendi esses dias, como alterar sua folha de estilo, e todo o layout da pagina, atraves de javascript.

Primeiro algumas considerações: Isso vai reforçar o uso de padrões web(webstandarts) nas paginas, por que o que acontece é ,  o script faz alterar a folha de estilo css ativa da pagina, ou seja, apenas vai carregar outro arquivo .css . Logo para que isso tenha o efeito desejado é necessário que o html seja semântico, pois assim pode-se usar css padronizados. Um mesmo (x)html, varios css .

Apesar do exemplo simples(não sou tão designer assim), o Manifesto é feito dessa forma, ele é gera apenas blocos simples de codigos XHTML. O layout todo é aplicado via css, posso fazer o layout que quiser(e minhas imagens permitirem) apenas por css. Um exmplo ótimo é o ZenGarden, todos os modelos de layout são apenas arquivos css diferentes, as imagens e etc são carregadas pelo css, e em todos usa-se o mesmo código (x)html. Entendem a importância dos padrões e layout css? Entre outros fatores…

Vamos ao trabalho então?

Aqui também aplicamos o uso de DOM,  e dos poderes do javascript, usando sua API de DOM, que você pede entender melhor nesse link muito bom. Resumindo um pouco é a capacidade de ler/alterar a estrutura da pagina, como pegar tags, atributos e conteúdos, muuuuito usado no dito AJAX e muitas vezes em RPCs também.

Primeiro vamos entender como carregar os estilos na pagina, vamos usar as tags "link" com rel="alternate stylesheet". Isso é o que carrega o css na pagina, para cada css vamos definir um "title", que usaremos para chamar esse arquivo. O "rel" é para que esse nao seja carregado, ele fica desabilitado. Usando todos os estilos assim, sua pagina sera carregada sem estilo (Ele é semântica? sem problemas então), e um estilo sera chamado com o script.

<link href="extras/estilos/segundo.css" rel="alternate stylesheet" type="text/css"  title="Dark" />

O código mágico é esse aqui:

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// by http://www.manifesto.blog.br/
    var padrao = "Basico" ;
            function troca(txt) {
                var i, a, main;
                 for(i=0;(a = document.getElementsByTagName("link")[i]);i++) {
                    if (a.getAttribute("type") == "text/css") {
                        a.disabled = true ;
                        a.setAttribute("rel", "alternate stylesheet") ;
                    }
                }
                for(i=0;(a = document.getElementsByTagName("link")[i]);i++) {
                        if (a.getAttribute("type") == "text/css" && a.getAttribute("title") == txt) {
                            a.disabled = false ;
                            a.setAttribute("rel", "stylesheet") ;                
                        }
                    }
                setCookie("estilo",txt,"99");
            }           
            function start() {
                var txt = getCookie("estilo");
                if (txt == null) { txt = padrao ; }
                troca(txt)
            }           
            function setCookie(c_name,value,expiredays) {
                var exdate=new Date();
                exdate.setDate(exdate.getDate()+expiredays);
                document.cookie=c_name+ "=" +escape(value)+
                ((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
            }                                           
            function getCookie(c_name) {
                if (document.cookie.length>0)
                  {
                  c_start=document.cookie.indexOf(c_name + "=");
                  if (c_start!=-1)
                    {
                    c_start=c_start + c_name.length+1;
                    c_end=document.cookie.indexOf(";",c_start);
                    if (c_end==-1) c_end=document.cookie.length;
                    return unescape(document.cookie.substring(c_start,c_end));
                    }
                  }
                return "";
            }               
            window.onload = start ;    //////////////////////////////////////////////////////////////////////////////// 

Explicando:

  1. A variavel "padrao" é o css a ser carregado caso nenhum esteja ativo.
  2. A ultima funcao, start(), deve ser chamada noo body.onload(). Esta cuida de usar o ultimo css selecionado ou o padrao.
  3. A funcao troca(txt), cria um loop atraves dos links, verifica quais possutem o atributo "type" como  "text/css" usando o getAttribute e desativa todos (a.disable) e, para o ie, altera o "rel" com setAttribute para "alternative stylesheet". Entao procura pelo pelo titulo e o ativa.
  4. As funções de cookies são para salvar e resgatar a ultima opção de css escolhida.
  5. Para alterar o css, basta chamar a funcao troca(txt) passado o txt com o title do css escolhido.

Um exemplo de uso é o menu Layout do manifesto. Você pode ver o código no fonte, guia rápido das funções usadas:

  • document.getElementByTagName() -> Cria um array dos elementos no documento com essa tag, na ordem apresentada no documento.
  • document.Seu_Elemento_Aqui.getAttributo() -> Retorna o valor do atributo de seu elemento selecionado.
  • document.Seu_Elemento_Aqui.setAttribut() -> Altera o valor de seu elemento.
  • document.Seu_Elemento_Aqui.disabled -> Valor, true ou false, do atributo disabled.

Quando referencio a.disabled , "a" ja esta definido como document.getElementByTagName("link)[0], ou seja é o primeiro elemento do meu documento com a tag "link".

Bom, básicamente é isso. É muito interessante o estudo de DOM e JavaScript, vale a pena eu aconselho, as possibilidades são infinitas, isso é um grão de area numa praia de possibilidades e eu ainda estou aprendendo. O Google entendeu o poder, e usa e abusa do mesmo em seus serviços.

Caso alguem tenha alguma sugestão ou estiver tendo problemas com isso eu fico feliz em ouvir e ajudar… alguem tem algo a dizer?