Arquivos de sites

jQuery – Introdução ao selectors (seletores) e Usando elementos, IDs e classes

Uma tarefa muito comum quando se está usando JavaScript, é ler e modificar o conteúdo da página. Para fazer isso, você precisa encontrar o(s) elemento(s) que você deseja modificar, e ai é onde o selector no jQuery ajudará você. Com o JavaScript normal, encontrar elementos pode ser extremamente pesado, ao menos que você precise encontrar um único elemento que tem um valor especificado no atributo ID. O jQuery pode ajudar você a encontrar elementos baseado em seus IDs, classes, tipos, atributos, valores de atributos e muito, muito mais. Ele é baseado no selectors do CSS e como você verá através desse tutorial, ele é extremamente poderoso. Quando usamos esse tipo de programa para fazer mudanças em seu site, é importante que você tenha autenticação de dois fatores (two factor authentication (em Inglês)) de modo que o seu site e computador não são compromissados.

Pela razão dessa ser uma tarefa tão comum, o construtor do jQuery vem em várias formas que recebem uma selector query como argumento (parâmetro), permitindo você localizar elementos com uma quantidade bastante limitada de código para uma eficiência ótima. Você pode instanciar o objeto jQuery simplesmente escrevendo jQuery() ou até mais curto usando o nome de atalho do jQuery: $().

Portanto, selecionar um conjunto de elementos é simples assim:

$(<query aqui>)

Com o objeto jQuery retornado, você pode então começar a usar e alterar os elementos que você encontrou.

Fonte

Usando elementos , IDs e classes

O selector #id

Um tipo de selector muito comum é o baseado em ID, que nós vimos no exemplo “Hello, world”. Ele usa o atributo ID de uma tag HTML para localizar o elemento desejado. Um ID deve ser único,então você deve apenas usar esse selectior quando você deseja localizar um único elemento. Para localizar um elemento com um ID específico, escreva um caractere hash (#), seguido pelo ID do elemento que você deseja localizar, assim:

$("#divTest")

Um exemplo disso em uso:

<div id="divTest"></div>
<script type="text/javascript">
$(function()
{
        $("#divTest").text("Test");
});
</script>

Agora, enquanto tiver apenas um único elemento que combina com a nossa query acima, você deve estar ciente que o resultado é uma lista, significando que isso pode conter mais de um elemento, se a query combina com mais de um. Um exemplo disso é combinar todos os elementos quais usam uma ou varias classes CSS.

O selector .class

Elementos com uma classe específica podem ser localizados escrevendo um caractere ponto (.) seguido pelo nome da classe. Aqui vai um exemplo:

<ul>
        <li>Test 1</li>
        <li>Test 2</li>
        <li>Test 3</li>
</ul>
<script type="text/javascript">
$(function()
{
        $(".bold").css("font-weight", "bold");
});
</script>

O selector element

Você também pode combinar baseado em elementos nos nomes das tags.

You can also match elements based on their tag names. Por exemplo, você pode combiner todos os links emu ma página assim:

$(“a”)

Ou todas as tags div assim:

$(“div”)

Se você usar um selector de multi-elemento (multi-element), como o selector de classe que nós usamos no exemplo anterior, e nó sabemos que nós estamos procurando por emento de um tipo específico, é uma boa prática especificar o tipo do elemento antes do selector. Não é apenas mais preciso, mas também é mais rápido para o jQuery processar, resultando em sites mais responsivos. Aqui vai uma versão reescrita do exemplo anterior, onde nós usamos esse método:

$("span.bold").css("font-weight", "bold");

Isso combinará todos os elementos span com “bold” como classe. Claro, isso pode ser usado com IDs e praticamente com todos os outros selector também.

Fonte: jquery-tutorial.net / jquery-tutorial.net

jQuery – Evento Ready e Encadeamento de método (Method chaining)

Como mencionado, é uma boa prática esperar o documento ser totalmente carregado (loaded) e pronto (ready), antes de trabalhar com ele. Isso também permite você ter seu código JavaScript antes do body (corpo) do seu documento, na sessão head (cabeçalho), senão diretamente ou através de um link para um arquivo JavaScript externo. Você pode fazer isso apenas colocando seu código dentro do evento ready do documento. Nós vamos usar o mesmo exemplo como no capítulo “Hello, world!”, mas dessa vez o código está dentro do evento ready:

<div id=”divTest1″></div>
<script type=”text/javascript”>
function DocumentReady()
{
$(“#divTest1”).text(“Hello, world!”);
}

$(document).ready(DocumentReady);
</script>

O que fazemos aqui é que criamos uma function (função), chamada DocumentReady, a qual deve ser disparadas assim que o documento estiver pronto para manipulação do DOM. Na última linha, usamos o método ready() para atribuir nossa função ao evento ready, para dizer ao jQuery que assim que o documento estiver pronto, nós queremos que ele chame nossa função.

Entretanto, nós podemos encurtá-la um pouco usando uma função anônima (anonymous function) do JavaScript em vez disso. Isso basicamente apenas significa que ao invés de declarar a função e dá-la um nome, nós simplesmente criamos ela e então imediatamente passamos a referencia à função ready(). Se você é novo em JavaScript, então isso pode parecer demasiadamente complicado, mas assim você se acostuma a isso, você talvez possa apreciar as poucas keystrokes e o menor espaço necessário para realizar o mesmo:

<div id=”divTest2″></div>
<script type=”text/javascript”>
$(document).ready(function()
{
$(“#divTest2”).text(“Hello, world!”);
});
</script>

Mas com certeza, isso ainda não foi curto o bastante para o time do jQuery, então eles decidiram criar uma versão (sobrecarga) do construtor do jQuery, que leva uma função ready como um parâmetro, para fazer isso ainda mais curto:

<div id=”divTest3″></div>
<script type=”text/javascript”>
$(function(){
$(“#divTest3”).text(“Hello, world!”);
});
</script>

No ultimo exemplo, nossa função anonima é passada diretamente ao contrutor do jQuery, que a atribui ao evento ready. Como você verá quando você testar o código, o evento é disparado assim que a página for carregada, a maioria das vezes tão rápido que você nem se quer percebe.

Como já descrito, envolver nosso código na função de evento ready é a melhor prática para trabalhar com jQuery em nosso documento, e portanto você verá esse tutorial usando essa abordagem na maioria dos exemplos, a não ser ignorado para manter o tamanho dos nossos exemplos baixo.

Encadeamento de método (Method chaining)

Também um outro aspecto de tantos outros aspectos realmente legais do jQuery é o fato de que a maioria dos métodos retornam um objeto jQuery que você pode então usar para chamar outro método. Isso permite você fazer um encadeamento de método, onde você pode chamar múltiplos métodos no mesmo conjunto de elementos, que é realmente agradável porque isso salva você e o navegador de ter que procurar o mesmo elemento mais de uma vez. Aqui vai um exemplo, e não se preocupe sobre os métodos do jQuery usados nos exemplos seguintes – eles serão explicados nos capítulos posteriores:

<div id=”divTest1″></div>
<script type=”text/javascript”>
$(“#divTest1”).text(“Hello, world!”).css(“color”, “blue”);
</script>

Isso funciona assim: Nós instanciamos um novo objeto jQuery e selecionamos o elemento divTest1 com o caractere $, que é o atalho para a classe jQuery. No retorno, nós pegamos um objeto jQuery, permitindo-nos manipular o elemento selecionado. Nós usamos aquele objeto para chamar o método text(), que define o texto ao(s) elemento(s) selecionado(s). Esse método retorna o objeto jQuery de novo, nos permitindo usar outra chamada de método diretamente no valor de retorno, que é o método css().

Nós podemos adicionar mais métodos se nós precisarmos, mas até certo ponto, a linha de código se tornará bastante grande. Felizmente para nós, o JavaScript não é muito rigoroso em relação a sintaxe, então você pode formatar como você quiser, incluindo linebreaks (quebra de linha) e indentações.  Por exemplo, isso irá funcionar muito bem também:

<div id=”divTest2″></div>
<script type=”text/javascript”>
$(“#divTest2”).text(“Hello, world!”)
.removeClass(“blue”)
.addClass(“bold”)
.css(“color”, “blue”);
</script>

O JavaScript irá simplesmente jogar fora os espaços extras em branco, quando interpretar o código e executa-lo como uma longa linha de código com várias chamadas de métodos.

Observe que alguns métodos não retornam o objeto jQuery, enquanto outro apenas retornam isso dependendo dos parâmetros que você passar pra ele. Um bom exemplo disso é o método text() usado acima. Se parâmetros não forem passados a ele, o texto atual do(s) objeto(s) selecionado(s) é retornado em vez do objeto jQuery, enquanto um único parâmetro provoca o jQuery a definir o texto especificado e retornar um objeto jQuery.

Fonte: jquery-tutorial.net / jquery-tutorial.net

Java: como a serialização de objetos pode salvar sua aplicação desktop


Em um dos meus clientes é muito comum o desenvolvimento de aplicações Java voltadas para o ambiente desktop, aonde não raro enfrento problemas sérios de performance e consumo de recursos. O objetivo deste post é expor como usando o recurso de serialização de objetos oferecido pela plataforma Java consegui resolver (ou ao menos minimizar ao extremo) este desafio.

Imagine a seguinte situação: sua aplicação desktop acessa informações presentes em um banco de dados relacional. Dado que você precisa de produtividade, opta por usar uma ferramenta ORM como Hibernate ou JPA. Não resta dúvidas de que trata-se de um recurso maravilhoso, mas infelizmente traz consigo um custo de memória (precisamos carregar o motor de mapeamento objeto relacional, além disto, muitas vezes usamos cacheamento que, ao menos em parte, fica em memória) e performance (trata-se de mais uma camada no sistema). Em algumas situações causa um aumento no tempo de carregamento dos nossos sistemas tão grande que, não raro, você se vê questionando o ganho real do seu uso.

Imagine agora outra situação: sua aplicação trabalha apenas com JDBC e, com isto, sua performance é superior à obtida usando JPA ou Hibernate (apesar de sua existência neste caso ser mais infeliz), porém há limitações no número de conexões que podem ser feitas ao SGBD e, pior ainda, o tempo gasto estabelecendo a conexão com o SGBD é alto. Em situações como esta, o tal “ganho de performance” por não se estar usando Hibernate se perde totalmente, pois você nem tem o cacheamento automático provido pelo ORM.

Em ambos os casos, como resolver o problema? Simples: evitando ao máximo que seja necessário estabelecer QUALQUER tipo de conexão com o servidor.

Entra em cena a serialização de objetos

Todo sistema possui informações cuja alteração seja rara, ou seja, registros que apenas são inseridos no banco de dados e em raras situações tenham seus dados alterados. Como exemplos posso citar um cadastro de fornecedores ou endereços. Tratam-se de informações que são usadas, em 90% dos casos, apenas para consulta ou na composição de tipos mais complexos. Pergunte-se: é realmente necessário sempre pedir ao SGBD estes dados?

Nestes casos, a serialização de objetos cai como uma luva. E se você está em um ambiente corporativo, é possível inclusive fazer com que um único usuário beneficie todos os demais com um custo adicional mínimo. Vou ilustrar a situação usando como exemplo uma aplicação desktop que precise expor em um formulário uma caixa de seleção contendo a listagem de fornecedores presentes no banco de dados.

Vamos supor que esta nossa aplicação use o Hibernate. Neste caso, ao criar uma nova instância do formulário, precisamos obter a listagem de fornecedores seguindo o seguinte procedimento:

  1. É criada uma consulta no Hibernate usando criteria ou HQL
  2. Esta consulta é transformada em comandos SQL que serão enviados ao driver JDBC
  3. O driver JDBC envia a consulta para o SGBD
  4. O SGBD executa a consulta e retorna o resultado para o cliente
  5. O driver JDBC traduz o resultado enviado pelo SGBD para um objeto java.sql.Recordset
  6. O Hibernate cria novas instâncias da classe Fornecedor e, via reflexão, preenche todos os seus atributos
  7. E, finalmente, é retornada uma lista contendo o resultado para o cliente

Se esta for a primeira consulta feita pela aplicação, o seu usuário ainda vai ter de sofrer um pouquinho com o carregamento do SessionFactory do Hibernate.

Agora, quer ver como as coisas ficam mais simples usando serialização? Suponha que eu já tenha serializado esta lista de fornecedores em um arquivo presente em minha rede. O seguinte procedimento seria adotado.

  1. É verificado se o arquivo existe na rede.
  2. Se o arquivo existe, então este é desserializado em uma lista de fornecedores e retornado ao cliente.
  3. Se o arquivo não existe, execute o longo procedimento exposto acima novamente, com a diferença de que, agora, você serializará o resultado em arquivo no final.

Observe que interessante: não precisei carregar o Hibernate nem comunicar-me com qualquer servidor. Claro, se o arquivo não existisse, todo o processo citado acima seria necessário, porém em um ambiente de rede, só precisaria ser feito uma vez pelo primeiro usuário que necessitasse da lista de fornecedores. Dai pra frente, todos os demais usuários obteriam o ganho de performance que apresentei.

Mas o que é serialização de objetos

Ok, talvez você esteja apenas começando a aprender Java e não saiba o que é esta tal de serialização. Porcamente falando, serialização é o processo de salvar em arquivo um objeto presente na memória do seu computador.

Se eu quisesse salvar a minha listagem de fornecedores em um arquivo, o código abaixo daria conta do recado:
1

E, para transformar o meu arquivo em objeto, de novo apenas três linhas fariam o trabalho pra mim.
2

Detalhe: só podem ser serializados objetos que implementem a interface java.io.Serializable.

Omiti as excessões apenas para expor como é um recurso absurdamente fácil de ser usado.

Armadilhas a serem evitadas

O principal desafio desta abordagem é manter o cache sempre atualizado. Tenho duas soluções para este problema. A mais simples é de tempos em tempos apagar os arquivos de cache da rede. A mais complexa consiste em, toda vez que for persistir uma novo registro no banco de dados, apagar os arquivos de cache.

Dica: evite ao máximo chamar a função exist() da classe java.io.File, pois esta é absurdamente cara, visto que a cada chamada acessa o gerenciador de segurança do Java. Dado que o objetivo de qualquer sistema é expor os dados para o usuário, você pode sempre, ao verificar a existência do cache, escrever código similar ao exposto abaixo:

3

Outra armadilha: em um ambiente de rede, evite serializar os dados no HD local do usuário. Sempre que possível, opte por usar um drive de rede. Assim, caso seja necessário uma atualização do cache imediata, você, como administrador do sistema, em último caso sempre poderá apagar o arquivo de cache, forçando o cliente a recriá-lo novamente.

Fique atento também ao que será serializado. Dados que apenas ocasionalmente são consultados não são um bom alvo. Opte apenas por aquelas informações que são vitais ao uso do seu sistema e cuja atualização seja rara.

E, a principal armadilha: JAMAIS use esta técnica em entidades que precisem ser constantemente atualizadas na base de dados.

Padrão: buscando um único registro

Há situações em que não é necessário buscar uma lista de registros, mas apenas um, o que normalmente é feito executando uma consulta por chave primária. Nestes casos, adotei um padrão bastante simples. Crio um diretório na rede chamado cache e, dentro dele, um subdiretório que identifique o tipo da minha entidade. No caso de fornecedores, chamo este diretório, por exemplo, de /cache/fornecedor. No interior deste diretório armazeno arquivos cujo nome corresponda à chave primária da entidade que desejo buscar no banco de dados.

Mas se o Hibernate já possui sistema de cache, pra que usar serialização?


Como diriam os candidatos a presidente em um debate… esta é uma pergunta importantíssima.

Simples: porque a serialização, tal como estou expondo neste post, deve ser usada ANTES da primeira chamada ao Hibernate, pois assim, em algumas situações, consegue-se evitar o carregamento deste framework e, consequentemente, nosso usuário final terá um sistema muito mais leve e responsível.

Se sua aplicação vai ser executada em um servidor nem sei se o uso desta técnica trará algum resultado que realmente valha à pena.

Conclusões

Uso esta técnica para resolver os problemas de performance que enfrento em aplicações desktop, aonde normalmente os recursos computacionais podem ser mais limitados (as malditas “máquinas brancas”). O que pude observar é que, nestes casos, obtenho ganhos de performance astronômicos, pois a comunicação com o SGBD é reduzida a apenas o estritamente necessário.

Outro ganho que obtenho é o tempo de inicialização da aplicação, pois é muito comum neste momento ser necessária a execução de alguma consulta no SGBD. Sendo assim, esta é uma técnica que, ao menos por enquanto, cai como uma luva quando aplicada ao ambiente desktop.

Aos que queiram se aprofundar mais no assunto, sugiro a leitura deste post: “The Java serialization algorithm revealed”, que explica com detalhes o processo de serialização: http://www.javaworld.com/community/node/2915

Agora: sabem o que me choca nesta história toda? Este recurso maravilhoso oferecido pela plataforma é raríssimas vezes usado pelos desenvolvedores. Da pra acreditar???

Fonte: iTexto – Henrique Lobo Weissmann