A única forma oficial de colocar uma aplicação na iTunes Music Store é a produzindo na linguagem Objective-C usando a SDK de desenvolvimento da Apple.
Porem, a SDK possui um componente chamado UIWebKit. Esse componente nada mais é que uma janela do navegador Safari, que pode ser usado pela aplicação.
O UIWebKit, assim como o Safari, possui um interpretador JavaScript. Isso permite que um desenvolvedor com habilidades em HTML, CSS e JavaScript utilize toda a força de um navegador moderno como o WebKit (SQLite, HTML5, Canvas, etc) para fazer fortuna na lojinha de Jobs.
Indo além, o tal do UIWebKit pode ser estendido para executar funções da SDK de dentro do interpretador JavaScript. Por exemplo: a funcionalidade que faz o iPhone vibrar não é disponível para a API JavaScript do Safari, porém código (Objective-C) pode ser escrito de forma que o JavaScript tenha acesso a tal função.
PhoneGap
Um projeto chamado PhoneGap tem a intenção de juntar em um só lugar os códigos que fazem a ligação entre o componente UIWebKit e as APIs publicas do iPhone OS.
Ele não é um framework nem uma API. Muito menos faz chamadas a API do iPhone que são de uso somente da Apple (API privada).
O PhoneGap é somente um esqueleto de aplicação com um Safari preenchendo toda a tela da aplicação e carregando o arquivo index.html da pasta www (que vai junto com a aplicação). É simples assim. Se você manja HTML, CSS e JavaScript poderia ficar rico também na App Store.
Poderia meu irmão, poderia.
Na semana passada alguns revisores da Apple começaram a recusar aplicações que levam pelo menos um pouco do PhoneGap. Essa semana, conforme reportado na lista de discussão do projeto, nenhuma aplicação foi aceita. Todas recebem a mesma reposta:
Após a análise da sua aplicação, ** não pode ser enviado para App Store devido ao uso de API privada.
O uso de APIs privadas é proibido conforme descrito no ponto 3.3.2 do “iPhone SDK Agreement”:
“Uma aplicação não pode instalar ou executar outro código por nenhum meio, incluindo sem limitação o uso de plug-ins, chamadas a outros frameworks, outras APIs ou outra forma.
Nenhuma código interpretado pode ser baixado e usado em uma aplicação, exeto o código que é interpretado e executado pelo ‘Apple’s Published APIs’ e seus interpretadores.”
A API do PhoneGap implementada na sua aplicação é um framework externo.
Por enquanto nenhuma outra posição da Apple ou dos desenvolvedores do PhoneGap foi tomada. A recomendação é que quem precisar colocar a aplicação na App Store não arrisque com o PhoneGap.
Essa é uma tradução de “Improve your jQuery-fu, write plugins” de Tomáš Kramár Trnava.
Escolhi traduzir esse texto pois ele foi o tutorial mais simples que encontrei quando precisei escrever um plugin. No final dele você será capaz de entender como o jQuery trabalha com plugins e poderá escrever os seus próprios.
jQuery é um framework JavaScript simples e poderoso que mudou minha forma de programar JavaScript. Um novo JavaScript dizem alguns com certa razão. O código que você cria é pura elegância.
Você começa com 10 linhas de jQuery que poderiam ter sido 20 linhas do tedioso JavaScript manipulando DOM. No final você acaba ficando com duas ou três linhas.
E esse numero pode ficar ainda menor se você refatorar o código para um plugin do jQuery.
Quando o assunto é escrever plugins, pessoas (tipo eu) normalmente pulam fora com medo. Eu ouvi sobre plugins de jQuery a bastante tempo mas nunca havia tentado escrever um. Quando pensava no assunto algumas idéias vinham na minha cabeça:
Deve ser difícil e por isso deixe isso somente para jedis
Isso deve precisar de um conhecimento profundo do jQuery
O que eu vou ganhar?
(Eu vim do mundo Java, imagine).
Nota do tradutor:
(Eu vim do mundo Ruby ;D).
Nada do que eu imaginava é verdade. Escrever um plugin é facil como escrever algo usando o jQuery. Não é necessario nenhum conhecimento especial. Tudo o que é preciso é extender um objeto jQuery. Algo como:
Lembra? Isso é JavaScript, não Java. O código acima é tudo que você precisa para criar um plugin. Dentro da função, $this é a referencia ao objeto jQuery de onde o plugin foi chamado.
No exemplo, $this é um objeto com os elementos
e você pode fazer de tudo com eles. Como o plugin retorna $this, você pode continuar executando metodos do jQuery usando “Method Chaining”.
De volta a minha última questão. O que você possivelmente vai ganhar criando um plugin?
Alto nivel de reusabilidade
Muitos pedaços de JavaScript são geralmente reaproveitáveis, mas criando um plugin você passa ele para outro nível.
Configuração
Isso é ligado ao ponto anterior. O cenário sem plugin é ter um pedaço de código que você copia e cola modificando para seu proposito. Isso pode ficar muito mais fácil com plugins. Você pode escrever o seu para, por exemplo, aceitar algumas opções. Veja como fica agora:
Elegância
O código acima parece melhor que um script inteiro, não parece?
Agora é a hora de mostrar um exemplo real. Vamos fazer um script para tornar clicável cada linha da tabela.
Sempre que eu queria fazer as linhas clicáveis eu copiava esse código e mudava a URL ou o nome do parâmetro.
Com o plugin fica assim:
settings = $.extend(defaults, settings); // escreve em cima das opções default com as opções enviadas
$this = $(this);
É interessante para quem pretende fazer scripts de Greasemonkey utilizar a biblioteca jQuery para agilizar o desenvolvimento. Para isso o código comentado a seguir vai ajudar:
// Verifica se o jQuery pode ser usado
function GM_wait() {
if(typeof unsafeWindow.jQuery == ‘undefined’) { window.setTimeout(GM_wait,100); }
else { $ = unsafeWindow.jQuery; letsJQuery(); }
}
GM_wait();
function letsJQuery() {
// pode usar o $ aqui ;D
}
Obs: se você utiliza outro navegador existem outras opções para executar “user scripts”. Uma delas é o GreaseKit para WebKit (Safari).
Algumas dicas de jQuery eu passava para amigos, mas agora encontrei uma coleção de Excelentes truques e dicas para jQuery que traduzi, adicionei comentários, retirei o que não acho legal e agora compartilho aqui:
Se você utiliza sempre o jQuery em seus sites, uma excelente maneira de acelerar o carregamento é usar o arquivo jquery-1.2.6.pack.js diretamente do Google Code. Além de diminuir o gasto com banda, o navegador do usuário faz cache do arquivo entre os vários sites que usam essa técnica o que dará uma experiencia de navegação melhor para o visitante.
O Google tem uma infra-estrutura de espelhamento ao redor do mundo, sendo o mais rápido e melhor serviço de distribuição de conteúdo (ou CDN para os íntimos).
Aproveite os milhões de computadores do Google e faça com que o jQuery seja carregado de lá.
Existem várias ferramentas para isso, mas ao invés de combinar eu ainda prefiro minimizar separadamente os scripts e CSSs. Uso para isso o YUI Compressor do Yahoo!
Combinar acho que vale mais para o Apache ou outros WebServers, onde a quantidade de requisições no servidor importava. Hoje com Nginx e outras soluções para o problema de escalabilidade a quantidade de conexões HTTP com o servidor não é um problema tão critico.
Já vi casos que um arquivo não compactado foi a diferença entre manter 1 servidor dedicado ou precisar “comprar” um novo. Fikdik de como escalar WowWowWow.
Em um computador atual isso não demora nada, mas lembre-se que o usuário utiliza equipamentos muito piores que seu Macbook Pro. Imagine eles em seus fracos iPhones, ou pior ainda, em um Opera Mobile.
Então mantenha o seletor fora do loop:
6 – Use o minimo possivel de manipulação com o DOM
Funções como .append(), .prepend(), .after(), .before() são relativamente custosas e podem deixar as coisas lentas.
É consideravelmente lenta perto de:
Escrever no DOM somente uma vez é um pouco mais rápido. Já que aqui estamos mesmo lutando por optimizações (lembrem-se dos mobiles), vale né?
7 – Coloque tudo dentro de um elemento antes de fazer uma inserção ao DOM
8 – Use IDs em vez de classes sempre que possivel
A função de busca por com CSS3 Selector é muito legal de se usar, mas o jQuery implementa ela em JavaScript, e usando o máximo que a API do DOM deixa. Isso as vezes não é o ideal para performance, acredite.
Navegadores como o WebKit já possuem implementação nativa dessa função, indo de acordo com o que foi pensado no framework Prototype, mas lembre-se, em desktop/notebook a hegemonia é de quem não IEmplementa novidades tão cedo.
No mercado de mobile, WebKit e Opera lutam para ver quem tem o maior numero de especificações da W3C implementadas.
Uma busca por ID no DOM quase sempre é mais eficiente que a busca por classe, prefira sempre usar ID.
9 – Dê um contexto para seus seletores
Eu tenho dúvidas quanto a eficácia de contextualizar os seletores via Javascript, comparada ao uso de contexto no CSS3. De qualquer forma as seguintes formas de uso são mais rápidas do que buscar um elemento no documento inteiro.
10 – Use encadeamento de funções
Uma das características mais legais do jQuery é a possibilidade de encadear métodos. Então, por exemplo, se você deseja alterar a classe de um elemento:
Provavelmente você aprendeu isso em seus primeiros 5 minutos de leitura sobre jQuery.
Note que continua funcionando mesmo com quebras de linhas (jQuery == JavaScript), o que significa que você pode escrever código assim:
Usar encadeamento também ajuda a diminuir a quantidade de seletores.
Mas ainda é possivel ir além. Digamos que você deseja executar várias funções em um elemento mas uma das primeiras funções muda o elemento selecionado de alguma maneira:
Nós selecionamos uma tabela, descemos para buscar celulas com a classe “primeiraColuna” e então a pintamos de vermelho.
Digamos agora que queremos colorir todas celulas com a classe “ultimaColuna” de azul. Já que usamos o método find(), filtramos todas as células que não tinham a classe “primeiraColuna”, assim seria necessario o uso de um seletor novamente ou então não poderiamos continuar encadeando, certo? Nah! O jQuery possui o metodo end() que reverte a última seleção, então você pode continuar encadeando tipo:
É também mais fácil do que você imagina escrever suas funções de forma que elas possam usar encadeamento.
Tudo que você precisa é fazer que suas funções modifiquem e retornem o mesmo elemento.
Bem legal!
11 – Saiba como usar a propriedade de animação
Quando eu comecei usar o jQuery eu adorei o fato de que é fácil usar animações pré-definidas como slideDown() e fadeIn() para conseguir alguns efeitos com incrível facilidade.
É também fácil ir ainda além por causa da facilidade que é usar o poderoso método animate().
Se você olhar os metodos slideDown() e fadeIn() dentro do framework verá que são apenas atalhos para o metodo animate().
O método animate() simplesmente pega qualquer estilo de CSS e aplica transições de um valor a outro. Então as mudanças nas propriedades width, height, opacity, background-color, top, left, margin, color, font-size e qualquer outra que você quiser podem ter animações!
É muito fácil animar todos itens do seu menu para 100 pixels usando isso.
Diferentemente de outras funções do jQuery, as animações são colocadas em fila de execução automaticamente. Se você quiser rodar uma segunda animação somente quando a primeira terminar, então é só chamar o método novamente sem precisar usar um callback.
Porém, se você você desejar que as animações ocorram no mesmo tempo, então insira ambas na mesma chamada assim:
O jQuery torna fácil adicionar eventos em elementos do DOM de forma inobstrusiva, o que é muito bom, mas adicionar muitos eventos é ineficiente. A delegação de eventos permite que você adicione em muitas situações menos eventos e atinja o mesmo resultado:
Vamos fazer uma função simples para tornar uma celula da tabela vermelha quando você clicar nela. Digamos que você tenha uma tabela com 10 colunas e 50 linhas, então são 500 delegações de eventos.
Não seria melhor se fosse possivel agregar o evento somente uma vez e então quando a tabela fosse clicada, chegar ao elemento que realmente foi clicado antes desse se tornar vermelho?
Para isso é que serve a delegação de eventos e isso é simples de implementar…
13 – Use classes (ou atributos) para armazenar estado
Essa é a maneira mais básica de guardar informação sobre um bloco de HTML. O jQuery facilita a manipulação de elementos utilizando classes, então se você precisa armazenar informações sobre o estado de um elemento, por que não adicionar uma classe extra nele?
Aqui vai um exemplo. Nós queremos criar um menu que expande. Quando você clica no botão nós queremos que o painel desça – slideDown() – quando ele tiver fechado, e que suba – slideUp() – quando estiver aberto.
Vamos começar com o HTML
Simples
Nós adicionamos uma classe extra na div de fora, que não possui outro proposito a não ser armazenar o estado do item. Então, tudo que precisamos é um evento de clique – click – para chamar o slideUp() ou o slideDown() no painel correspondente quando o botão é clicado.
if (menu_item.hasClass("expandido")) {
menu_item.removeClass('expandido').addClass('colapsado');
painel.slideUp();
} else if (menu_item.hasClass("colapsado")) {
menu_item.removeClass('colapsado').addClass('expandido');
painel.slideDown();
}
});
Esse é um exemplo bem simples, mas você pode adicionar classes extras para armazenar todos tipos de informações sobre um elemento DOM (pedaço de HTML).
De qualquer forma, melhor ainda é a próxima dica.
14 – Melhor ainda, use o método data() que é interno do jQuery para armazenar estados
O jQuery possui um metodo interno chamado data() que pode ser usado para armazenar informações de chave/valor sobre qualquer elemento DOM. Armazenar um pouco de informação é simples assim:
Nós podemos usar o exemplo da dica anterior. Vamos utilizar o mesmo HTML, porém ao invéz da classe “expandido” usamos o metodo data().
var item_menu = $(this).parent();
var painel = item_menu.find('.painel');
Para mais informações sobre os metodos data() e removeData() veja a documentação.
15 – Escreva seu proprio seletor
O jQuery possui vários seletores prontos para ajudar na seleção de elementos pelo ID, class, tag, atributo e muito mais. Mas o que fazemos quando é preciso usar seletores que vão além do que o jQuery deixa?
Bom, uma possivel solução seria adicionar classes nos elementos e usa-las para seleciona-los. Uma outra maneira é extender os seletores assim:
$('.box:mais100px').click(function() {
alert('O elemento que você clicou possui mais de 100 pixels de altura');
});
Primeiro criamos um seletor que acha qualquer elemento que é maior que 100 pixels. Depois usamos isso para adicionar uma ação de clique – click – em todos esses elementos.
O jQuery já quebra um galho ao facilitar a manipulação de elementos DOM, mas também adiciona metodos uteis para iterar, filtrar, clonar, juntar arrays ou remover elementos duplicados.
17 – Use a função “noconflict” para evitar conflitos com outros frameworks
A maioria dos frameworks para JavaScript usam o simbolo $ como atalho. Para evitar problemas existe uma solução simples, a função .noconflict() que permite definir outro atalho para o framework:
18 – Use função anonima para evitar conflitos com outros frameworks
Uma boa maneira de evitar conflitos no JavaScript (não somente com jQuery) é o uso de uma função anonima.
O que for executado dentro do bloco não muda com o escopo global, evitando problemas com nomes duplicados de variaveis e funções.
19 – Saiba quando uma imagem terminar de carregar
Use o método .load() em um elemento de imagem (IMG) com um callback. Simples assim:
É importante que o elemento já esteja no HTML.
20 – Sempre use a última versão
O framework está sendo constantemente melhorado por John Resig, seu criador. Sempre que uma versão nova sai ela possui melhoras na performance e se mantem atualizada com o que existe de novo nos navegadores.
A próxima versão do jQuery (1.3) virá com uma nova engine chamada Sizzle que além de mais rápida vai utilizar as funções querySelectorAll e getElementsByClassName já disponiveis nos navegadores mais modernos.
Então, utilize sempre a última versão.
21 – Como saber se um elemento existe?
Você não precisa checar se um elemento existe antes de manipular ele por que o jQuery simplesmente não faz nada caso o elemento não estiver no DOM. Mas as vezes você pode precisar executar algum pedaço de código que depende da existência de um elemento, para isso use:
22 – Adicione uma classe no HTML para saber que o JavaScript está disponivel
Logo que o jQuery carregar use ele para adicionar uma classe chamada “JS” na tag HTML:
Como isso só acontece quando o JavaScript (e o jQuery) estiverem prontos, você pode usar CSS para controlar quando um elemento deve aparecer somente quando o usuário estiver com JavaScript habilitado.
23 – Return ‘false’ para evitar a continuação de um evento
Quando você tem:
E adiciona um evento tipo assim:
Vai perceber que o bloco de código vai ser executado, porem o navegador irá para o endereço do link. Você pode usar “href=’#'” para evitar isso, mas assim a página irá voltar para o topo quando a ação de click for executada.
Para evitar isso, adicione um “return false;” ao fim do bloco de código:
24 – Atalho para a função “ready”
Você já deve estar acostumado a usar
Pois saiba que pode economizar um pouco de código simplesmente usando:
25 – Identifique váriaveis do tipo jQuery
Se você começar usar as dicas para evitar chamadas desnecessarias as funções do jQuery vai perceber que no seu código o número de variaveis carregando objetos jQuery irá aumentar bastante.
Para evitar que você se confunda e chame a função de seleção – $() – em um elemento que já é jQuery, identifique variaveis que carregam objetos do jQuery com um $ antes do nome.
Ufa! 25 praticas ninja para ajudar sua produtividade com jQuery. Se você tiver mais alguma boa pratica e quer compartilhar, por favor comente aqui
E se você gostou do artigo, por favor espalhe pelo mundo.
Ter uma tabela de referências em mãos, com as funções disponíveis na linguagem de programação ou framework que você está utilizando ajuda muito.
Manter essa tabela sempre aberta, e não em outra aba do navegador também é um bom truque, que evita o desvio de atenção.
A Colorcharge preparou uma versão especial para iPhone da documentação do jQuery. Com o nome de jTouch o projeto deixa as funções e formas de uso do jQuery na ponta do dedo (aha).
Quem não possui o aparelho da Apple, pode também imprimir uma versão pronta para o formato A4. Check this out.
Isso torna o framework compatível com uma gama maior de browsers. Agora as funcionalidades especificas de cada browser são implementadas dependendo das funções disponíveis e não mais simplesmente da versão do navegador.
Nesse mesmo sentido, o código responsável pela busca de elementos foi totalmente reescrito e agora usa – quando possível – CSS3 Selectors nativo. Assim, em navegadores como o WebKit, quando a função $() for usada quem realmente fará o trabalho é a implementação nativa do navegador. Insanamente mais rápido, huh?
WebKit é o navegador do iPhone e de alguns aparelhos Nokia.
Como em mobile performance no JavaScript é uma preocupação, excelente movimentação do jQuery.
Na última semana reuni vários novos skills de desenvolvimento para iPhone. Não foi fácil. O pessoal que desenvolve para a plataforma parece que não curte muito compartilhar o que sabe… foda…
Seguindo a dica do @evertonfraga fui dar uma brincada com um plugin do jQuery que facilita a diversão com as funções de touch (touchstart, touchend, touchmove) e com a API de gestures (gesturestart, gesturechange, gestureend): jQuery Touch.
O problema é que versão original tem algumas cagadas jumentais.
O cara chamava N! vezes a função $() do jQuery e isso deixava o Safari puto (digo, muito lento).
Uma das utilizades da “função $()” do jQuery é buscar um elemento na página.
Na mais rápida das hipóteses, a busca pode ser feita pelo id, tipo $(’#content’), o que vai encadear uma chamada ao método document.getElementById(’content’) do navegador.
No WebKit/Safari essa função é bem rápida e chamar ela em um computador normal não deve deixar nada lento, mas meu amigo, no iPhone é outra história.
Arrumei rapidinho e agora tudo roda mais suave. Com o tempo devem surgir mais melhoras, mas você já pode se divertir também:
Sabe como é. Sou solteiro, moro em São Paulo e trabalho em uma startup. O que eu iria fazer depois de um dia puxado no trabalho?
Comecei a trabalhar em cima de uma versão enxuta do jQuery para rodar somente no Safari (focando o iPhone) as 10 da noite. O checkout no repositório do jQuery demorou um pouco, mas logo eu já estava com a versão mais atual e com o mais importante: os testes.
A missão era retirar toda e qualquer gambiarra do código do framework responsáveis por faze-lo passar nos testes em todos navegadores, deixando somente o que seria executado no Safari (WebKit).
Eu nunca havia trabalhado em um ambiente 100% coberto por testes. Foi bem mais fácil cumprir a missão coberto por testes. Enquanto fui retirando os browsers sniffings rodava os testes para saber se estava no caminho certo.
No final não sobrou nenhum browser sniffing no jQuery (mas eu deixei o objeto $.browser lá para quem precisar).
Aproveitei e alterei para as buscas por $(’#id’) usarem a função “document.querySelector” que é uma implementação do CSS3 Selectors da W3C. De qualquer forma isso foi mais uma brincadeira do que algo para aumentar a performance.
Antes de substituir o mecanismo de busca do jQuery para usar as funções de busca que WebKit e Firefox agora implementam, perguntei ao John Resig sobre. Segundo ele a próxima versão do jQuery vai contar com um novo seletor que saberá quando usar os métodos nativos.
Agora eu tenho essa versão do jQuery sob medida para o Safari. A diminuição no tamanho do arquivo foi minima e quem usar essa versão deve ter ganho em processamento muito pequeno (sim, estou desmotivando as pessoas a usarem). O que valeu foi o aprendizado, e agora eu sei alguns dos planos do John.
Quando o novo jQuery sair a intenção vai ser deixar somente a parte que utiliza esses métodos, esquecendo os navegadores que não implementam. Como o alvo é o Safari do iPhone, nenhum problema
Então certo dia lá estava eu, tentando uma expressão regular para interpretar (ou parsear) HTML. Uma tarde inteira tentando “achar” um elemento do HTML e substituir por outro. Apanhando da Regex…
Levantei, bebi agua e reclamei alto da vida. O Marco me perguntou o motivo do momento de fúria. Expliquei e fui submetido a mais um daqueles momentos “como eu sou tão estupido” que está ficando comum comentar aqui.
“Usa o jQuery porra!”
Uma das principais coisas fodas do jQuery é como ele trata o DOM (Document Object Model) das páginas e como ele permite buscar pela arvore de elementos “desse tal” de DOM. Ele armazena tudo de maneira bem leve e consegue procurar absurdamente rápido dentro dos elementos do HTML.
E o melhor: o jQuery permite que você crie essa “arvore de elementos” enviando uma string que contenha HTML/xHTML (XML para ser mais exato).
O código fala mais que a histórinha:
Para procurar o elemento você pode usar “CSS Selector” (igualzinho CSS3) e ainda tem a ajuda das várias funções de busca que o jQuery possui.
Ah! Vale lembrar que não é só no jQuery que é possível usar essa mágica. Existem bibliotecas parecidas em outras linguagens.
Em Ruby eu venho usando bastante a Hpricot. Elas utiliza a mesma lógica de armazenamento do jQuery e permite uso de seletores CSS e XPath.
Em PHP já me mostraram a SimpleHtmlDOM, parece bem fácil também.
Procure saber biblioteca é legal para usar na sua linguagem preferida e nunca mais tenha problemas em parsear HTML utilizando expressões regulares.
Eu adoro o jQuery. Não tem um dia que não brinque um pouco com ele.
É claro que ele não é a solução para a pobreza mundial, nem sequer para a tristeza dos emos. Como tudo nessa vida de softwares, é importante saber quando vale a pena adicionar à porrada de linhas de código que o jQuery adiciona ao carregamento da página, quando vale a pena usar algo que encaixa melhor no problema.
De qualquer forma eu tenho um motivo muito bom para você esquecer o discurso de quem é “anti” qualquer coisa, como o jQuery…
jQuery agora é algo que está no navegador
Há algum tempo atrás, o Google anunciou que hospedaria algumas bibliotecas de JavaScript, tais como jQuery; prototype; script.aculo.us; MooTools; dojo, apoiando os desenvolvedores a linkarem a parada diretamente de lá. A idéia é que com muitos desenvolvedores usando as bibliotecas que estão hospedadas no mesmo lugar, o usuário muito provavelmente terá uma copia da local em cache sempre.
E isso só vai aumentar. Podemos básicamente acreditar que o usuário já tem o jQuery (ou coloque aqui o seu framework JS preferido) pronto para ação no navegador! Ainda resta algum outro motivo para não utilizar?