Closure em Javascript
E aí povo!
Depois de umas férias de nerdice, queria voltar a falar sobre algumas técnicas muito interessantes que mais uma vez a melhor linguagem existente no planeta implementa. Eu estava devendo uma, quando falei sobre Callbacks em Javascript, os Closures.
Eu gostaria de falar também sobre Currying, que também utiliza closure, mas ia ficar um post muito longo. Recomendo bastante a leitura desse tema no blog do Milfont, onde ele fala sobre Currying em Javascript e sobre como é utilizado em callbacks.
O que é ..
Em ciência da computação e na programação uma closure é uma função que referencia variáveis livres no contexto léxico. Uma closure ocorre normalmente quando uma função é declarada dentro do corpo de outra, e a função interior referencia variáveis locais da função exterior. Em tempo de execução, quando a função exterior é executada, então uma closure é formada, que consiste do código da função interior e referências para quaisquer variáveis no escopo da função exterior que a closure necessita.
Wikipédia: http://pt.wikipedia.org/wiki/Closure
O conceito de Closures foi desenvolvido e primeiramente implementado em Scheme, que é uma linguagem de programação de paradigma funcional.
Embora Javascript não seja essencialmente de paradigma funcional, ela permite usar algumas técnicas de programação funcional, Closure é uma delas.
Como funciona?
Bom, num post passado eu havia dito que os callbacks utilizavam closures, de fato, algumas implementações usam, como?
Olha esse caso:
function h(f){
setTimeout(function(){
f()
},2000)
}
Aqui, h recebe um argumento f, portanto f é uma variável livre no escopo de h, e portanto é vista no escopo da função setTimeout. Quando a setTimeout for executar a função f, ela vai saber exatamente quem é a função f, pois está “amarrada” a função h.
function h(f){setTimeout(function(){f()},2000) }
Vamos tornar mais claro essa noção de variáveis livres. Vou usar mais um argumento agora na função h.
function h(f, n){
setTimeout(function(){
f(n)
},2000)
}
E agora eu chamo ela passando uma função como argumento e um número como segundo argumento:
h(function(i){alert(i)}, 20)
Se tudo correr bem, vai dar um alert de 20. Essa função não tem utilidade alguma, serve apenas para ilustrar como ocorre o closure.
Vamos para um exemplo um pouco mais complexo, pois usaremos o retorno de função. Eu considero a programação funcional em js complexa, levando em conta o início do meu aprendizado nessa técnica. Lógico que agora é muito mais simples e claro, mas quando comecei a aprender sobre isso eu pastei. Mas eu me considero meio burrinho, tenho certeza que você vai pegar o jeito da coisa bem mais rápido, se já não souber…
Vou criar uma função que soma os valores de um array e dentro dessa função vou construir outra função anônima que será retornada.
A idéia é , chamar uma função passando um array como argumento e receber uma outra função que fará a soma dos valores do array por um número, passado como argumento da chamada dessa função retornada.
“Caraaaaaay, que porra é essa?!?!?!?” . Tenha calma, fica mais fácil mostrar do que explicar:
function sumArr(arr){
return function(by){
for(var x = 0; x<arr.length; x++)
arr[x] = arr[x] + by
return arr
}
}
Portanto:
var somamais = sumArr([1,2,3])
somamais agora é uma função, que ainda enxerga as variáveis livres de “sumArr”. Então:
somamais(5)
>>[6, 7, 8]
Senhoras e senhores, temos o closure ali!!! A função sumArr é tal que possui uma variável de nome “arr” atrelada à uma outra função declarada internamente. Neste nosso caso, uma função anônima retornada após a chamada de “sumArr”.
Não é sensacional !?!??!
Não é maravilhoso !?!?!?!
Não é melhor que sexo ?!?!?!? ( tá bom…não… ¬¬)
Não é tudo, mas é muito interessante.
Trazendo um pouco para a vida real. Digamos que queremos fazer uma Library, uma biblioteca que use paradigma funcional em javascript para tratar Arrays.
function Library(arg1){
return function(action){
return ({
'?' : function(arg2){
for(var x = 0; x<arg2.length; x++)
if(arg2[x] == arg1) return true
return false
}
})[action]
}
}
Library.begin= function(){return Library}
Bom, o funcionamento desse código eu vou deixar para que você sozinho entenda. Mas, usei closure até não poder mais aí.
Nessa minha Mini-Library, eu só tenho uma funçãozinha de teste, que verifica se um valor existe em um array, retorna um valor booleano, assim:
Library.begin()
(4)('?')([4, 50, 39, 55, 79])
Responde true, já que o 4 está no array passado como argumento.
Programação funcional tende a ser bastante complicado para se entender, aliás, é esse um dos contras das linguagens de paradigma funcional como Scheme. É muito interessante, em alguns casos bem elegante, mas o código se torna muito confuso a medida que vai aumentando sua complexidade.
Sacaram a melosquência ?
Flw galera, aqueleabraço.
Filed under: Javascript, Técnicas de programação | Leave a Comment
Filtro Solar – por Pedro Bial
A maioria dos meus posts são bem técnicos, mas chega uma hora que cansa né?
Ser nerd toda hora cansa…
Então, eu não gosto só de códigos bem feitos, gosto de textos bem feitos, curto bastante citações, pensamentos bem redigidos e lembro até hoje de um vídeo que meu professor de Física (Aldo, Universitário) do cursinho nos mostrou para passar uma mensagem para a turma.
Se você já conhece, veja de novo prestando atenção na letra, se você não conhece, recomendo que veja.
Um grande abraço.
Nunca deixem de usar filtro solar!
Se eu pudesse dar uma só dica sobre o futuro,seria esta: use filtro solar.Os benefícios a longo prazo do uso de filtro solar
estão provados e comprovados pela ciência;
já o resto de meus conselhos não tem outra base confiável além de minha própria experiência errante.Mas agora eu vou compartilhar esses conselhos com vocês.
Aproveite bem, o máximo que puder, o poder e a beleza da juventude.
Ou, então, esquece… Você nunca vai entender mesmo o poder
e a beleza da juventude até que tenham se apagado.
Mas, pode crer, daqui a vinte anos, você vai evocar as suas fotos e
perceber de um jeito – que você nem desconfia hoje em dia
quantas tantas alternativas se lhe escancaravam à sua frente,
e como você realmente tava com tudo em cima.
Você não é tão gordo(a) quanto pensa!Não se preocupe com o futuro.
Ou então preocupe-se, se quiser, mas saiba que pré-ocupação
é tão eficaz quanto mascar chiclete
para tentar resolver uma equação de álgebra.
As encrencas de verdade de sua vida tendem a vir de coisas que nunca
passaram pela sua cabeça preocupada, e te pegam no ponto fraco às quatro
da tarde de uma terça-feira modorrenta.
Todo dia enfrente pelo menos uma coisa que te meta medo de verdade.
Cante.Não seja leviano com o coração dos outros.
Não ature gente de coração leviano.
Use fio dental.
Não perca tempo com inveja.
Às vezes se está por cima,
às vezes por baixo.
A peleja é longa e, no fim,
é só você contra você mesmo.
Não esqueça os elogios que receber.
Esqueça as ofensas.
Se conseguir isso, me ensine.
Guarde as antigas cartas de amor.
Jogue fora os extratos bancários velhos.
Estique-se.Não se sinta culpado por não saber o que fazer da vida.
As pessoas mais interessantes que eu conheço não sabiam,
aos vinte e dois, o que queriam fazer da vida.
Alguns dos quarentões mais interessantes que conheço ainda não sabem.
Tome bastante cálcio.
Seja cuidadoso com os joelhos.
Você vai sentir falta deles.
Talvez você case, talvez não.
Talvez tenha filhos, talvez não.
Talvez se divorcie aos quarenta, talvez dance ciranda em suas bodas de diamante.
Faça o que fizer, não se auto-congratule demais, nem seja severo demais com você.
As suas escolhas tem sempre metade das chances de dar certo.
É assim pra todo mundo.Desfrute de seu corpo.
Use-o de toda maneira que puder. Mesmo.
Não tenha medo de seu corpo ou do que as outras pessoas possam achar dele.
É o mais incrível instrumento que você jamais vai possuir.
Dance.
Mesmo que não tenha aonde além de seu próprio quarto.
Leia as instruções, mesmo que não vá segui-las depois.
Não leia revistas de beleza. Elas só vão fazer você se achar feio.Dedique-se a conhecer os seus pais.
É impossível prever quando eles terão ido embora, de vez.
Seja legal com seus irmãos. Eles são a melhor ponte com o seu passado
e possivelmente quem vai sempre mesmo te apoiar no futuro.
Entenda que amigos vão e vem, mas nunca abra mão de uns poucos e bons.
Esforce-se de verdade para diminuir as distâncias geográficas
e de estilos de vida, porque quanto mais velho você ficar,
mais você vai precisar das pessoas que conheceu quando jovem.More uma vez em Nova York, mas vá embora antes de endurecer.
More uma vez no Havaí, mas se mande antes de amolecer.
Viaje.Aceite certas verdades inescapáveis:
Os preços vão subir. Os políticos vão saracotear.
Você, também, vai envelhecer.
E quando isso acontecer, você vai fantasiar que quando era jovem,
os preços eram razoáveis, os políticos eram decentes,
e as crianças, respeitavam os mais velhos.
Respeite os mais velhos.
E não espere que ninguém segure a sua barra.
Talvez você arrume uma boa aposentadoria privada.
Talvez case com um bom partido.
Mas não esqueça que um dos dois pode de repente acabar.Não mexa demais nos cabelos senão quando você chegar aos quarenta
vai aparentar oitenta e cinco.
Cuidado com os conselhos que comprar,
mas seja paciente com aqueles que os oferecem.
Conselho é uma forma de nostalgia.
Compartilhar conselhos é um jeito de pescar o passado do lixo, esfregá-lo,
repintar as partes feias e reciclar tudo por mais do que vale.Mas no filtro solar, acredite!
Filed under: Pensamentos | Leave a Comment
Css Orientado a Objetos
Css Orientado a Objetos?
E por que não ?
Eu sei, orientação à objetos é um paradigma de programação, sei também que Css não é uma linguagem de programação.
Mas nós podemos usar alguns conceitos desse paradigma tão usado e usá-lo ao nosso benefício, mesmo com uma linguagem de formatação.
A orientação à objetos nos ajuda a abstrair a complexidade de uma aplicação de forma coesa e organizada, usando conceitos
que temos em nossa mente para descrever de maneira bem clara o funcionamento de um conjunto ou sistema, de forma mais humana,
podemos modelar o código para atender aos requisitos necessários para seu funcionamento adequado.
A idéia de Orientação à Objetos é muito boa, o fato do Css não ter todos os requisitos para ser uma linguagem orientada à objetos,
não significa que não possamos usar alguns conceitos de Orientação à Objetos. Quais conceitos?
- Abstração
- Encapsulamento
- Classe
- Herança
- Reuso de código
Como utilizar estes conceitos voltados para o Css?
Abstração
Abstração não é um conceito exclusivo de OO, porém é um deles.
Antes de solucionar um problema, precisamos visualizá-lo em nossa mente e tentar simplificá-lo de forma bem primitiva a fim de
tornar sua solução fácil também, é aqui que tudo começa. Vamos então gerar um problema hipotético e conveniente:
Problema: Implementação de uma caixa com todas as bordas arredondadas .
Great! Temos um problema.
Existem várias formas de se resolver um problema, principalmente um problema clássico como este, mas visualizar o
problema e definir as principais propriedades da solução é a parte mais importante. A implementação da solução é pessoal, tendo seus prós e contras.
Deixa a abstração deste problema para depois.
Encapsulamento
No Css, podemos definir a formatação de um elemento de acordo com o seu elemento pai. Ex:
.caixa p{ border:1px solid red }
Com isso podemos “encapsular” estes comportamentos dentro de um elemento pai, ou seja, só seus filhos terão estes comportamentos.
Classe e Objetos
NOsso problema pede uma caixa com bordas arredondadas, certo?
Existem vários tipos de caixas, então podemos pensar que essa caixa é de um tipo, do tipo com bordas arredondadas.
Bom, estamos aqui usando o conceito de classe, dando um tipo para um elemento. Logo a instância ou o objeto deste tipo seria cada implementação do seu html =).
Lembra da abstração? Então, visualize tudo na sua cabeça a partir de agora.
A minha solução para as bordas arredondadas é a seguinte:
Usei uma caixa maior, dentro dela utilizei 3 retângulos de mesma largura da caixa maior porém com altura pequena, empilhados um em cima do outro.
Um dos retângulos é o “header” digamos assim. Ele abrigará duas outras caixas menores, uma flutuada à esquerda e outra à direita. Estas caixas menores serão responsáveis
por exibir as imagens de bordas arredondadas.
O segundo retângulo, é o do meio da pilha, ele abrigará de fato o conteúdo da caixa maior. Sua altura não é definida, ele cresce em altura de acordo com o tamanho do seu conteúdo.
Já o terceiro retângulo é uma réplica do “header” ele será um “footer” desta caixa e será exatamente igual ao primeiro retângulo.
A idéia é fazer com que o conteúdo do segundo retângulo empurre para baixo as bordas arredondadas inferiores, já que não sabemos qual será o tamanho da caixa em cada aplicação.
Ótimo, mas vamos ver um pouco de prática né ?
Ok, criei então um tipo para esta caixa, o tipo “rounded” ( Arredondado em inglês ), prefiri seu nome em inglês por ser menor.
Esta “Classe” ficou assim:
.rounded .r-header,
.rounded .r-footer,
.rounded .r-content,
.rounded .borders,
.rounded { display:block }
.rounded .r-header,
.rounded .r-footer{ background-repeat:repeat-x }
.rounded .borders{ line-height:0 }
.rounded .top-left,
.rounded .bottom-left{
float:left;
background:left no-repeat
}
.rounded .top-right,
.rounded .bottom-right{
float:right;
background:right no-repeat
}
Perceba que para esta solução, os dois retângulos que abrigam as imagens das bordas tem o mesmo comportamento, então otimizei ao máximo o Css para os comportamentos iguais.
A Classe “borders” se refere aos elementos de borda dentro dos retângulos, todos os 4 elementos de borda tem esta classe, e todos com comportamentos iguais.
Tudo foi definido apenas por classe, porque eu queria que não ficasse preso a apenas tipo de elemento html e para não ser necessário mexer no Css para funcionar com outros elementos.
Bom, então essa “Classe” seria nossa abstração para o tipo borda arredondada. Agora é onde chegamos na parte mais interessante sobre este post, onde utilizamos os dois últimos conceitos de OO, Reuso de código e Herança.
Já resolvemos o problema de bordas arredondadas, não precisamos resolvê-lo de novo, essa é uma das coisas interessantes quando pensamos em OO.
Eu queria fazer uma caixa com uma faixa cinza no topo e na parte inferior, que lembra uma janela do Mac. ( Eu disse “Lembra” )
Mas a janela do Mac é toda bonitinha, e tem os 4 cantos arredondados. Ótimo, então agora eu faço um objeto novo, ou melhor, uma classe nova, uma caixa arredondada do estilo Mac, ou seja, uma caixa do tipo arredondada do tipo mac.
Agora usamos o reuso de código, atráves de uma simples herança, usando a abstração da classe “rounded” com atributos encapsulados, para gerar uma nova caixa de novo tipo:
/*
* @author Eduardo Ottaviani
* @require {rounded.css}
*/
.macboxgray .r-header{ background-image:url(../../img/back-top.png) }
.macboxgray .top-right{ background-image:url(../../img/right-top.gif) }
.macboxgray .top-left{ background-image:url(../../img/left-top.gif) }
.macboxgray .r-footer{ background-image:url(../../img/back-bottom.png) }
.macboxgray .bottom-left{ background-image:url(../../img/left-bottom.gif) }
.macboxgray .bottom-right{ background-image:url(../../img/right-bottom.gif) }
.macboxgray .borders{
height:24px;
width:5px
}
.macboxgray .r-header,
.macboxgray .r-footer{ height:24px }
Da hora né? Olha quanta linha foi necessária para criar este novo objeto.
Você poderia estar se perguntando se não seria mais legível se eu nomeasse a classe assim:
.rounded.macboxgray
Seria, principalmente para ficar bem nítido e claro de quem a macboxgray herda, porém usar duas classes juntas não é uma boa idéia só por causa do ie6. Por que ?
Ao definir uma borda:
.rounded.macboxgray{ border:1px solid blue }
No iE6, outro objeto que tem apenas a classe “rounded” também herdaria a borda azul =/ . No mínimo esquisito….
Para que você entenda como foi feita a herança, vou mostrar o html desta caixa:
<form class="macboxgray rounded"> <span class="r-header"> <span class="borders top-left"></span> <span class="borders top-right"></span> </span> <fieldset class="r-content"> <p> lorem ipsum dolor amec lorem ipsum dolor amec lorem ipsum dolor amec lorem ipsum dolor amec </p> </fieldset> <span class="r-footer"> <span class="borders bottom-left"></span> <span class="borders bottom-right"></span> </span> </form>
Olha ali, o nosso objeto é um form, do tipo macboxgray rounded.
Portanto o macboxgray é uma derivação da classe rounded, uma implementação específica da classe “rounded”.
Conseguem entender o que estou querendo dizer?
Importando as duas classes, eu só precisaria mexer nas definições específicas para aquela tela que estou montando, dando margin, padding, float etc. Lembrando que nesta solução, eu teria de alterar o width na classe .macboxgray e alterar a altura no .macboxgray .r-content, já que o .r-content que detêm o conteúdo, poderia deixar um tamanho fixo por exemplo com scroll ou deixa-lo no padrão, em auto, crescendo conforme o conteúdo cresce.
Prestem atenção, embora eu tenha utilizado classes para os elementos html, neste post essas classes são implementadas conforme seu uso na linguagem Css reaproveitando comportamentos iguais, não são dessas classes que estou falando, estou falando da classe “Rounded”, uma classe que existe apenas na nossa cabeça, um tipo de objeto que é nossa solução para caixas arredondadas e que poderá ser estendido futuramente para outros tipos de caixa, também de bordas arredondadas.
Isso é um exemplo de como enxergar as coisas como objetos no Css. Um dia eu pensei nisso e acho que esta forma de pensar trás, além de reuso de código, visão simples e organizada do código Css, tornando muito mais estensível a linguagem do que já é, são inúmeras as possibilidades do que pode ser feito pensando dessa forma.
Pensa num objeto layout, que pode ser do tipo líquido ou fixo por exemplo, olha que coisa louca….pode viajar, foda né?
O Diego Eis mostrou no tableless.com.br uma implementação de layout líquido e com apenas uma alteração ele passava a ficar fixo. Olha aí uma idéia para uma outra classe…
Outra coisa boa é que, eu testei exaustivamente esta implementação de borda arredondada e funcionou muito bem, então, na hora de fazer um outro tipo de objeto que o estenda, perderei menos tempo com os bugs já resolvidos com esta implementação bem sucedida.
Quando criei o macboxgray, não precisei de novo me preocupar com os problemas das bordas arredondadas, elas já estavam solucionadas, precisei apenas pensar nos seus problemas pontuais.
Css não tem métodos, portanto, para sabermos da sua implementação na prática precisamos de uma documentação.
Este código acima html é colocado como exemplo dentro do comentário do rounded.css, para que um dia ao reutilizar o código, basta colar e será mais rápido de lembrar do seu funcionamento.
Então é muito importante uma mínima documentação, lá no código do macboxgray, deixei nos comentários que ele precisa da classe .rounded, na palavra-chave “required”. Lógico, não é necessário de novo colocar o exemplo do html dentro deste código, já que ele herda de rounded e já está lá seu exemplo.
Essa técnica particiona ao máximo o seu Css, aumentando consideravelmente o número de arquivos se você for uma pessoa criativa, então é interessante ser bem organizado na sua estrutura de pastas, até pensando em montar um próprio framework.
Terá casos onde será melhor você utilizar um único arquivo Css ao invés de ficar importando vários objetos de pequenos arquivos, consumindo a banda, então use o bom-senso para estes casos, copie os códigos e cole em um arquivo único, comprima-o se necessário, algumas linguagens server-side já fazem isso dependendo do framework que esteja usando, Rails faz isso. De qualquer forma no Css, desde que esteja bem encapsulado, juntar é muito mais fácil do que separar.
É claro que esta solução tem também suas desvantagens. Uma é que o código fica um pouco maior do que o necessário no html.
Mas pessoalmente acho um preço muito baixo a se pagar, se tiver a certeza de que funciona nos navegadores que deseja.
Eu usei aquela mesma solução de bordas arredondadas de um post meu, “Bordas Arredondadas”, lembra? Porém dei uma enxugada maior no código css e alterei algumas coisinhas.
That´s all folks! Espero que tenham entendido minha idéia e se alguém aí tiver mais idéias, por favor poste que eu quero saber!
Quem quiser ver como ficou a implementação das bordas clique aqui, visualize o código fonte para entender o que fiz.
Um grande abraço.
Filed under: Boas práticas, Css, Idéias, Técnicas de programação | Leave a Comment
Callbacks em Javascript
Eu as vezes tenho o mau-hábito de pensar que o que eu sei todos sabem e acabo menosprezando certos assuntos interessantes por causa disso.
Já ouviu falar em callbacks ? Se você trabalha com Javascript com certeza já ouviu, mas você sabe o que são e para que servem ?
jQuery usa muito, mas se você não sabe o que são eu explico =D.
Digamos que você precise de uma função que crie uma div após 5 segundos numa tela. É besta, mas é apenas um exemplo…
Só que essa função é muito útil para você e toda hora você precisa usá-la. Então você arruma ela, deixa ela o mais simples possível porque parece ser uma solução boa para aquele propósito.
Mas você acaba notando que aquela solução tem que ser modificada toda hora para atender aos requisitos de cada projeto. Como assim?
Eu tenho essa função de criar div a cada 5 segundos, bonitona:
function div(target, conteudo){
setTimeout(function(){
var div = document.createElement("div")
div . innerHTML = conteudo
target . appendChild( div )
}, 5000)
}
Mas no outro projeto eu só quero trocar a classe da div. Eu teria de reescrever a função de novo:
function div(target, classe){
setTimeout(function(){
var div = document.createElement("div")
div . className = classe
target . appendChild( div )
}, 5000)
}
Toda hora reescrever a função que faz a mesma coisa… que idiotice né ? Bom, nesse caso, é uma boa prática usar callbacks.
Callbacks nada mais são do que funções que são passadas como argumento de uma outra função. Vou explicar melhor.
Se eu fizer:
function f( variavel ){
alert( variavel )
}
var a = 5
f(a)
Vai me dar um alert mostrando 5.
Se eu fizer:
function f2(){
alert( " Função 2 " )
}
f(f2)
O alert vai me retornar o protótipo da função, ou seja, a função foi passada para a outra função normalmente.
Só, que para se executar a função é necessário sempre usar o parênteses.
A função f não vai chamar a função f2, só vai mostrar o corpo dela. Como eu faria para chamar a função f2 na f?
Simples, só chamá-la na f:
function f( funcao ){
funcao()
}
Pronto, agora, se eu fizer:
f( f2 )
O alert vai mostrar “Função 2″. Ou seja, a f2 foi passada como argumento e a f pega essa função,
usa uma nova variável chamada “funcao” e faz a chamada dela.
Sabendo disso, daria para nós generalizarmos a nossa primeira função utilizando esse conceito.
function div(target, callback){
setTimeout(function(){
var div = document.createElement("div")
target . appendChild( div )
callback?callback(div):null
}, 5000)
}
A função continua criando uma div e colocando num alvo qualquer após 5 segundos,
porém na última linha do seu código eu verifico se a variável callback está setada, ou seja, se foi passado algo como segundo argumento.
Se eu passar uma função a f vai fazer o seguinte:
callback = funcao
Agora a função está generalizada e callback é uma função qualquer.
Se eu quiser criar um div após 5 segundos e adicionar uma classe nele eu faria:
div(
document.body,
function(div){
div.className = "Classe"
}
)
Se eu quiser criar uma div e botar um conteúdo ao invés de colocar uma classe eu faria:
div(
document.body,
function(div){
div.innerHTML = " Meu conteúdo"
}
)
De novo, para entender, o que a f vai fazer nesse último caso é :
target = document.body
callback = function (div){ div.innerHTML = "Meu conteúdo"}
E então chamará:
callback(div)
O argumento “div” diz respeito ao elemento criado na função div(), pois é na função div() que eu faço a chamada do callback.
**Callbacks utilizam conceitos como programação funcional e closures. Mas isso é assunto para outro post
Eu utilizei esse exemplo para demonstrar dois casos interessantes onde as callbacks são usadas.
Um caso é quando queremos generalizar uma função para utilizá-la de várias formas diferentes sem precisar mexer nela.
Outro caso é quando não sabemos quando algo termina para poder começar outro.
Por exemplo, eu uso uma função que faz um efeito de fadeOut (sumindo elemento aos poucos) , mas após esse efeito,
queria a mostrar um alert na tela. Como você sabe que terminou o efeito para poder chamar outra função? Agora você já sabe !!!
Filed under: Boas práticas, Javascript, Técnicas de programação | 7 Comments
Para quem trabalha desenvolvendo sites de forma não obstrutiva, já precisou usar muitas vezes o window.onload, certo?
Isso não tem nenhum problema de compatibilidade entre os browsers ou algo do tipo, mas tem um incoveniente. O script só é executado quando todos os elementos E imagens serem carregados.
Geralmente o que deixa um site pesado são as imagens, no caso de uma tela pesada com muitas imagens ou imagens grandes (em kb), o tempo de carregamento aumenta muito e muitas vezes o script não pode esperar tanto tempo.
Os frameworks já implementam esse onready, como o jQuery por exemplo.
Mas e se não quiser usar um framework no seu projeto ?
Há algumas soluções prontas na internet, já vi algumas muito boas como a do Micox.
Uma vez enquanto eu desenvolvia um projeto, pensei numa solução bem simples eacabei usando em alguns projetos sem frameworks, gostaria de compartilhar com vocês.
A minha idéia é a seguinte:
function ready(fn){
var clock = setInterval(
function(){
if(document.body) {
fn()
return clearInterval(clock)
}
},1
)
}
A idéia é repetir uma função indefinidas vezes testando se existe o objeto document.body.
Teóricamente só existirá o objeto quando todos os seus filhos tiverem sido criados.
No caso de existir, a função termina de executar o teste e executa uma função passada como parâmetro.
Embora a idéia de repetir algo infinitas vezes pareça um pouco intimidadora, penso que um possível loop infinito aconteça no caso do body não ter sua tag fechada (mas aí também né…), mas nunca testei isso.
Fiz alguns testes com alert para saber quantas vezes a função é executada e na maioria dos casos só repetia uma vez. Os objetos parecem ser criados muito rapidamente, antes do segundo milissegundo da repetição da função.
A forma de usar seria essa:
ready(function(){
alert( " Carreguei =) " )
})
Dentro da função você colocaria qualquer comando ou outra função…
É essa minha idéia, se alguém achar algo de ruim poste, para tentarmos melhorar essa estratégia.
Aquele abraço.
Filed under: Idéias, Javascript | 3 Comments
Já tentaram recuperar algum valor do Css de objetos onde não foi atribuído o estilo pelo Js e nem foi atribuído em in-line?
Vou explicar melhor:
div#box{
width:100px;
height:100px;
border:1px solid red;
}
<div id="box"></div>
O que aconteceria se eu fizesse:
alert(
document.getElementById("box")
.style.height
)
????
O retorno seria vazio: “”.
Duas formas rápidas de se resolver isso seria usar Css in-line, setando diretamente na tag o valor do “height”, ou setar o valor inicialmente com javascript.
As duas formas são ruins, pra falar a verdade. Existe uma forma de pegar esses valores com javascript e pra variar temos dois js, um para navegadores e outro para o iE.
Para os navegadores:
document.defaultView .getComputedStyle(elemento, null) .getPropertyValue()
Para o iE:
Elemento.currentStyle
Bom, pelo menos o código do iE é bem mais elegante.
Eu já havia postado sobre isso e uma possível solução no fórum.
Mas não apareceu ninguém para fazer alguma crítica ( construtiva ) sobre meu algoritmo.
Que era esse:
function $style(elem, att){
if(elem.currentStyle)
return (elem.currentStyle[att])
return document.defaultView
.getComputedStyle(elem, null)
.getPropertyValue(att)
}
Porém ela pode ser melhorada, e percebi isso lendo um dos meus blogs favoritos que é o Milfont. O Milfont nesse post falou sobre o design pattern Bridge para encapsular o X-Browser.
O problema do meu algoritmo é que toda vez que a função $style fosse chamada, ela precisaria testar qual navegador eu estou usando. Nesse caso, o script tem 5 linhas e não há perda de desempenho significante, porém, vamos já nos acostumar a fazer da forma mais correta desde já.
Seguindo a lógica que Milfont descreveu, o algoritmo poderia ser melhorado para este formato:
var currentStyle = new function X(){
if(document.all)
return( function(el, att){
return el.currentStyle[att]
})
return ( function(el, att){
return document.defaultView
.getComputedStyle(el, null)
.getPropertyValue(att)
})
}
Pronto, agora ao chamar currentStyle os navegadores estariam usando o document.defaultView. Já os iE´s da vida usariam o element.currentStyle.
var box = document.getElementById("box")
alert( currentStyle( box, "height" ) )
É isso aí, abraços.
Filed under: JXC | 3 Comments
Olá de novo.
Esses dias me vi na necessidade de usar uma caixa com borda arredondada e pensei em uma maneira de fazê-la, queria compartilhar com vocês.
Para montá-la eu usei uma miniaturização da estrutura de layout padrão de sites. Um header, dentro dele duas bordas esquerda e direita, o conteúdo central e o footer com bordas esquerda e direita.
As bordas estão dentro do header e do footer. Pensei em fazer as bordas, o header e o footer com span e o conteúdo com div.
Ficou assim o Html:
<div class="rounded"> <span class="r-header"> <span class="top-left"></span> <span class="top-right"></span> </span> <div class="r-content"></div> <span class="r-footer"> <span class="bottom-left"></span> <span class="bottom-right"></span> </span></div>
E o Css:
.rounded{ display:table; width:20% }
.r-header,
.r-footer,
.r-content { display:block; clear:both }
.top-left,
.top-right,
.bottom-left,
.bottom-right {
display:block;
line-height:0px;
width:6px; height:24px;
}
.top-left, .bottom-left{ float:left }
.top-right, .bottom-right{ float:right }
.r-header, .r-footer{ height:24px; background-repeat:repeat-x }
.top-left{ background:url(left-top.gif) no-repeat }
.r-header{ background-image:url(back-top.png) }
.top-right{ background:url(right-top.gif) no-repeat }
.bottom-left{ background:url(left-bottom.gif) no-repeat }
.r-footer{ background-image:url(back-bottom.png) }
.bottom-right{ background:url(right-bottom.gif) no-repeat }
.r-content{border:1px solid silver ; height:auto; }
Claro, fazendo com classes pois se quisesse montar várias caixas desta numa página, ficaria no mínimo trabalhoso ficar replicando várias id´s. Burrice.
Mas, melhor ainda seria se eu não precisasse inserir o mesmo html toda hora pra cada elemento com borda arredondada. Então, entra o Js:
function rounded(css, context){
var t = context? context.getElementsByTagName("*") :
document.getElementsByTagName("*")
for(var x=0; x<t.length; x++)
if(
t[x].className &&
t[x].className.match(/rounded/)
){
var temp = t[x].innerHTML
var content = '<span class="r-header">'
content += '<span class="top-left"></span>'
content += '<span class="top-right"></span>'
content += '</span><div class="r-content">'+ temp +'</div>'
content += '<span class="r-footer"><span class="bottom-left">'
content += '</span><span class="bottom-right"></span></span>'
t[x].innerHTML = content
}
var link = document.createElement("link")
link.rel = "stylesheet"
link.type = "text/css"
link.href = css
document.getElementsByTagName("head")[0].appendChild(link)
}
Como funciona, rounded recebe 2 parâmetros, o segundo é o escopo de onde deseja procurar seus elementos, se não passar o segundo parâmetro a função procura no documento todo objetos que tenham a classe “rounded”. O primeiro parâmetro é a localização do Css que usou para formatar as bordas arredondadas.
Eu particularmente prefiri fazer o Css separado neste caso, porque era necessário o scripttag para atualizar as caixas no FF.
Achando os elementos ele pegará cada um deles e fará cópia de seu conteúdo, posteriormente atualiza o conteúdo colocando as tags html necessárias para formatar a caixa arredondada concatenado com o conteúdo antigo. Bem simples. Há formas mais rápidas e melhores de se fazer um script desse, mas isso é pra mais tarde =)
Ou seja, se usar a classe “rounded” em um form, o conteúdo do form será guardado, neste form serão colocadas as tags span contendo as bordas junto com uma div de classe “r-content” contendo todo o conteúdo antigo do formulário.
Se o Js não for carregado ou se o browser do usuário não permitir Js, a página será exibida corretamente, porém sem as estilizações.
Veja um exemplo do código funcionando aqui.
Legal né? Mas o grande lance é saber fazer a caixa de modo que possa reaproveitá-la, ou seja, pode aumentar o tamanho dela ou diminuir, ela deve ficar bem renderizada, certinha. Depois se precisar redimensionar, alterar as bordas ou formatar uma caixa específica, basta adicionar um id pra ela no seu Css.
É isso, abraço.
Filed under: Css, Html, JXC, Javascript | 1 Comment
Código Fonte bonito
Bom, deixando as apresentações de lado, vamos ao primeiro post nerd hehehe.
Queria começar com algo bem leve, deixar a programação pesada mais pra frente.
Como você escreve seus códigos? Eu apenas vi um blog falando sobre uma parte do assunto que quero comentar aqui e foi no clientside. O post era sobre: Devo usar ponto-e-vírgula?
Em Javascript, não é necessário realmente o uso do ponto-e-vírgula e meu estilo de programar é parecido com o do Elcio neste aspecto. Eu me importo com a apresentação do código, seja lá qual for a linguagem, então além de me preocupar com a lógica do programa, na sua reutilização, na sua generalização, eu também me importo com a sua “cara”.
Vou mostrar o que eu estou querendo dizer, implementando uma classe:
function Pessoa(nome, idade, sexo, profissao){
var nome = nome
var idade = idade
var sexo = sexo
var profissao = profissao
this.fala = function(fala){
if(typeof fala=="string"){
alert(fala)
}
else{
alert("O tipo de fala precisa ser uma string!!!")
}
}
}
Normal certo?
O meu jeito de codificar:
function Pessoa
(nome, idade, sexo, profissao){
var nome = nome
var idade = idade
var sexo = sexo
var profissao = profissao
this.fala = function(fala){
(typeof fala=="string") ?
alert(fala) :
alert("O tipo de fala precisa ser uma string!!!")
}
}
Faz exatamente a mesma coisa, não tem nenhum ganho de velocidade nem nada do tipo. Mas pessoalmente acho muito mais bonito dessa forma, sem chaves caso tiver apenas uma instrução, sem ponto-e-vírgulas e quando o número de parâmetros for grande, quebro a linha no prototipo da função e SEMPRE indentando.
Isso ajuda na documentação do script, ajuda aos meus olhos e ajuda a me achar no meio de um código gigantesco.
É a mesma coisa com arrays:
var lista=new Array() lista[0]="Pera" lista[1]="Uva" lista[2]="Maça" lista[3]="Salada Mista"
Forma que eu prefiro:
var lista = [ "Pera", "Uva", "Maça", "Salada Mista" ]
Chamada de funções:
var Edu = new Pessoa( "Eduardo Ottaviani", 24, "Masculino", "Programador" )
Concatenação de strings:
ajax.url = ( "pagina.php?sid=" + Math.random() + "&query=" + document.forms[0].elements[0].value )
Antigamente não se usava muito essa forma de codificar, mas depois dos “callbacks” usados em algumas bibliotecas Javascript como Jquery, onde você muitas vezes precisa passar uma função como argumento, essa maneira começou a ficar mais comum.
Fica horrível fazer a chamada de uma função passando vários argumentos numa linha só!!!
Eu gosto de generalizar os códigos para que fiquem úteis em outras aplicações, geralmente antes de fazer um function eu já planejo onde eu posso usar aquilo mais tarde. Nessas, às vezes é necessário usar 1 ou 2 argumentos a mais na função, então sempre utilizo a forma mais “bonita” de codificar.
Enfim, é a maneira que eu sinto mais confortável, então não estranhe porque a partir deste post, todos os outros terão esse mesmo padrão de codificação.
Um abraço.
Filed under: Boas práticas | 1 Comment
Edu, the beginning

Não é só o Batman que teve um começo. Esse é o meu primeiro post em um blog próprio, espero que seja um blog interativo, de discussão, de aprendizado e sempre que possível, engraçado, já que para viver no Brasil é necessário um excelentíssimo bom humor!
E como vai ser o blog? NERD.
Quero dar a minha contribuição para a comunidade de Desenvolvimento Web, timidamente, espero que seja interessante para os que estão começando, será esse meu público alvo. Mesmo assim, será muito importante para mim a discussão de temas com programadores/desenvolvedores mais experientes já que o principal motivo de eu estar começando nessa vida blogueira é o aprendizado.
Muitos blogs aos quais visito me foram muito úteis no começo e ainda são, aprendi muita, muita coisa mesmo através deles. Espero que meu blog seja de grande utilidade.
Com certeza a maioria dos posts será sobre Javascript, Css e Xhtml, não terá só assuntos nerds, mas serão a maioria, então prepare-se!!!
Aiaaaaaaaaaaa!!!
Filed under: Uncategorized | Leave a Comment
Entradas recentes
Categorias
- Boas práticas (3)
- Css (2)
- Html (1)
- Idéias (2)
- Javascript (4)
- JXC (2)
- Pensamentos (1)
- Técnicas de programação (3)
- Uncategorized (1)