JavaScript ninja com jQuery
-
Upload
reinaldo-junior -
Category
Technology
-
view
6.839 -
download
3
description
Transcript of JavaScript ninja com jQuery
![Page 1: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/1.jpg)
Reinaldo Junior
http://reinaldojunior.net
![Page 2: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/2.jpg)
(ou ao menos ouviu falar?)
![Page 3: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/3.jpg)
![Page 4: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/4.jpg)
![Page 5: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/5.jpg)
![Page 6: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/6.jpg)
![Page 7: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/7.jpg)
![Page 8: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/8.jpg)
Todo mundo construía seus layout com tabelas.
Camadas de conteúdo e apresentação juntas. Pouca flexibilidade, baixa performance e
desorganização. Mas, era bonito e produtivo
![Page 9: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/9.jpg)
Separando a apresentação do conteúdo. Menor footprint Maior rapidez e clareza Maior organização leva à produtividade Acessibilidade (universalidade) Um passo inicial para Web Standards e
Marcação Semântica. Mas nem tudo foi perfeito...
![Page 10: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/10.jpg)
Programação Client-Side, controle dos diferentes navegadores/SO’s e do fluxo de navegação.
Camadas de comportamento e conteúdo juntas.
Imaturidade, baixa confiabilidade, falta de profissionais e ferramentas, diferentes implementações (proprietárias).
![Page 11: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/11.jpg)
![Page 12: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/12.jpg)
Anatomia de um Ogro (ou JS Obtrusivo)
•Não acessível•Destrutivo•Irritante•Assustador•Obtrusivo
![Page 13: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/13.jpg)
Obtrusive“1. Sticking out; protruding. 2. Noticeable;
prominent, especially in a displeasing way. 3. Pushy. ”
Obtrusivo“Um ogro deitado no meio do caminho,
pronto pra criar confusão”
<a href="javascript:abreNoticia(123);">Ler notícia</a>
<a href=“#“ onclick=“abreNoticia(123);”>Ler notícia</a>
<a href=“noticia.php?id=123“ onclick=“abreLink(this.href);”>Ler notícia</a>
![Page 14: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/14.jpg)
![Page 15: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/15.jpg)
“Na história Japonesa, um ninja (忍者, ninja) é um guerreiro, treinado em artes marciais, especializadoem uma varidade de artes de guerra não-ortodoxas. Os métodos utilizados pelos ninjas incluemassassinato, espionagem, furtividade, camuflagem, armas especializadas e um vasta coleção de artesmarciais.”
Wikipédia (http://en.wikipedia.org/wiki/Ninja)
“Os Japoneses desenvolveram as artes Ninja ao extremo, criando assassinos mortais, que podem entrar em qualquer lugar sem serem notados e agir quando menos esperado.”
The Illuminated Lantern (http://www.illuminatedlantern.com/cinema/archives/ninja.php)
![Page 16: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/16.jpg)
Anatomia de um Ninja (ou JS Não-obtrusivo)
•Acessível•Degradativo•Funcional•Belo
Não-Obtrusivo“1. Not noticeable or
blatant; inconspicuous”
“Um ninja que chegasorrateiramente, quaseimperceptível e faz seutrabalho”
![Page 17: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/17.jpg)
Boas práticas e padrões Separar o comportamento do conteúdo Melhorar funcionalidade, não impor Degradação Graciosa AJAX DOM Scripting Cross-Browser Scripting Delegação (e não Manipulação) de Eventos
![Page 18: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/18.jpg)
Temporada de caça aos Ogros
![Page 19: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/19.jpg)
(Jiraya, Tartaruga Ninja, Ninja Gaiden, Sub-zero ou Naruto – você escolhe)
![Page 20: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/20.jpg)
Fornecem facilidades para JS Não-Obtrusivo Possuem geralmente as mesmas
funcionalidades. Abordagens/filosofias/focos diferentes Exemplos: Prototype, MooTools, extjs, YUI,
GWT, Dojo, jQuery, Rico, Spry
![Page 21: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/21.jpg)
![Page 22: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/22.jpg)
Filosofia: “write less, do more” Intuitividade Praticidade Acorrentamento Licensa MIT e GPL Se Microsoft e Nokia podem, porque eu não? Google, Mozilla, IBM, Dell, BBC, Digg,
Amazon, Sourceforge, Wordpress, Drupal...
![Page 23: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/23.jpg)
(chega de papo e vamos ao que interessa!)
![Page 24: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/24.jpg)
jQuery (1.2.6) Firefox Firebug
FirePHP Web Developer Toolbar Opera, Safari e... Internet Explorer
![Page 25: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/25.jpg)
Básicos Hierárquicos Avançados
Filtros
Formulários
Filhos
![Page 26: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/26.jpg)
* elemento .classe #id seletor1, seletor2, seletor3
* {border: 1px solid red}
input {padding: 3px;}
.alinhadoEspecial {margin-left: 50px;}
#menuNavegacao {width: 300px;}
h1, h2, .titulos, #tituloHome {font-family: Tahoma;}
h1#primeiro.discreto { text-transform: lowercase; }
![Page 27: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/27.jpg)
ancestral descendente (dentro de...)
pai > filho (imediatamente dentro de...)
anterior + próximo (imediatamente depois de...)
anterior ~ irmãos (depois de...) – CSS3
#conteudo p {font-family: Arial;}
body > div {margin-left: 200px;}
label + input {border: 1px dotted red;}
h2.discreto ~ a {text-decoration:none;}
![Page 28: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/28.jpg)
:first / :last :eq(índice) / :not(seletor) / :even / :odd :lt(índice) / :gt(indice) [atributo] / [atributo=valor] / [att1][att2]
table:first { border: 1px solid blue; }
table *:not(tr) { padding: 5px; }
table.zebra td:even { background: black; }
#navegacao li:lt(3) { color: blue; }
input[name][type=text] { color: red; }
![Page 29: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/29.jpg)
:input :text / :password / :hidden :button / :submit / :reset :radio / :checkbox :enabled / :disabled :checked / :selected
:input { border: 1px dotted yellow; }
form :radio { margin-left: 5px; }
:checkbox:checked { text-decoration: line-through; }
![Page 30: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/30.jpg)
:nth-child( ... ) :first-child :last-child :only-child
ul li:nth-child(3){text-decoration: overline;}
table tr:first-child { background: yellow; }
tr td:last-child { backgound: red; }
div:only-child { width: auto; }
![Page 31: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/31.jpg)
jQuery
jQuery( seletor, *contexto )
jQuery( html )
jQuery( elementos )
jQuery( callback )
each( callback ) get( *índice )
![Page 32: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/32.jpg)
Métodos de “Traversing” (ou “aproximando-se sorrateiramente”)
![Page 33: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/33.jpg)
Encontrando quem você procura
add( seletor )
not( seletor )
filter( seletor / função )
eq( índice )
hasClass( classe )
is( seletor )
andSelf() / end()
![Page 34: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/34.jpg)
Indo até quem você procura
parent( *seletor ) / parents( *seletor )
children( *seletor )
siblings( *seletor )
prev( *seletor )
next( *seletor )
prevAll( *seletor )
![Page 35: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/35.jpg)
Métodos de “Attributes” (ou “caindo na mão”)
![Page 36: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/36.jpg)
attr( nome, *valor ) / attr( propriedades ) removeAttr( nome ) addClass( classe ) / removeClass (classe ) css( nome, *valor ) / css( propriedades ) height( *valor ) / width( *valor ) html( *valor ) text( *valor ) val( *valor )
![Page 37: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/37.jpg)
Métodos de “Manipulation” (ou “causando um estrago maior”)
![Page 38: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/38.jpg)
append[To]( conteúdo ) prepend[To]( conteúdo ) [insert]after( conteúdo ) [insert]before( conteúdo ) wrap[Inner/All]( html/elemento ) replace[With/All]( conteúdo/seletor ) empty() remove( seletor ) clone( [copiar-eventos] )
![Page 39: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/39.jpg)
Métodos de “Events” (ou “esperando a hora de dar o troco”)
![Page 40: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/40.jpg)
bind( tipo, *dados, função ) unbind( *tipo, *função ) one( tipo, *dados, função ) trigger( tipo, *dados ) triggerHandler( tipo, *dados )
![Page 41: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/41.jpg)
focus( *função ) , blur( *função ) click( *função ), dblclick( *função ) keydown( *função ), keyup( *função ) keypress( *função ) select( *função ) change( *função ) error( *função ) submit( *função )
![Page 42: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/42.jpg)
load( função ), unload( função ) scroll( função ), resize( função ) mousedown( função ), mouseup( função ) mousemove( função ) mouseover( função ), mouseout( função ) hover( entra, sai ) toggle( uma, outra )
![Page 43: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/43.jpg)
Métodos de “Effetcs” (ou “fazendo a mágica acontecer”)
![Page 44: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/44.jpg)
show/hide( *speed,*função ) toggle() slide[Up/Down]( *speed, [*função ) slideToggle( *speed, *função ) fade[In/Out]( *speed, *função ) slideTo ( speed, opacidade, *função )
![Page 45: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/45.jpg)
Métodos de “AJAX” (ou “invocando a irmandade secreta”)
![Page 46: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/46.jpg)
load(url, *dados, *callback) $.post(url, *dados, *callback) $.get(url, *dados, *callback) $.getJSON(url, *dados, *callback) $.getScript(url, *dados, *callback) $.ajax( opções )
![Page 47: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/47.jpg)
Métodos de “Utilities” (ou “tornando as coisas mais fáceis”)
![Page 48: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/48.jpg)
$.each( objeto, callback ) $.extend( alvo, obj1, obj2, ... ) $.unique( array ) $.grep( array, callback, *inverter) $.map( array, callback ) $.inArray( valor, array ) $.isFunction( variável ) $.trim( string )
![Page 49: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/49.jpg)
Extendendo o jQuery (ou “ensinando novos truques a macacos velhos”)
![Page 50: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/50.jpg)
Maneira simplificada de se criar plugins Abordagens
Estender a classe jQuery (métdos ou seletores)
Estender um objeto jQuery
Permite integrar funcionalidades à filosofia jQuery
![Page 51: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/51.jpg)
Métodos
Funções utilitárias
Independentes do Documento (DOM)
jQuery.extend({
min: function(a, b){
return a < b ? a : b;
}
})
![Page 52: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/52.jpg)
Seletores Estendem a abstração
jQuery.extend(jQuery.expr[":"], {
anamed: "a.name==undefined”,
unamed: "a.name==‘’”
});
$(‘*:anamed’) $(‘*:unamed’)
![Page 53: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/53.jpg)
Adiciona funcionalidades que dependam do funcionamento do jQuery
jQuery.fn.extend({check: function() {
this.each(function() { this.checked = true; });},uncheck: function() {
this.each(function() { this.checked = false; });}
});
![Page 54: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/54.jpg)
Proteja seu código Proteja o ambiente Mantenha acorrentável Mantenha intuitivo
![Page 55: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/55.jpg)
O que é isso?
(function() {
//Seu código
})();
![Page 56: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/56.jpg)
Que tal?
function teste() {
//Seu código
};
teste();
![Page 57: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/57.jpg)
Qual o problema?
var externa = 0;
(function(){
externa += 10;
})();
![Page 58: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/58.jpg)
E agora?
var externa = 0;
(function(){
externa += 10;
(function(){
externa += 10;
})();
})();
![Page 59: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/59.jpg)
http://pt.wikipedia.org/wiki/Closure Pode causar erros Pode ser útil (macros, por exemplo)
var eventos = [‘click’, ‘focus’, ‘blur’, ...];
jQuery.each(eventos, function(i, nome){
jQuery.protype[nome] = function(fn){
return this.bind(nome, fn);
};
});
![Page 60: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/60.jpg)
Qual o problema?
var externa = 0;
(function(){
var externa;
externa += 10;
})();
![Page 61: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/61.jpg)
E agora?
var externa = 0;
(function(){
var externa;
externa += 10;
(function(){
externa += 10;
})();
})();
![Page 62: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/62.jpg)
Seu código e o ambiente ficam protegidos
Seu código pode coexistir com outros códigos aleatórios do site
Seu código pode coexistir com outras cópias da sua biblioteca
Seu código pode ser utilizado em outra biblioteca
![Page 63: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/63.jpg)
(function($){
//Suas variáveis locais
//Seu código
})(jQuery);
![Page 64: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/64.jpg)
Lembra?
jQuery.fn.extend({
check: function() {
this.each(function() { this.checked = true; });
},
uncheck: function() {
this.each(function() { this.checked = false;
});
}
});
![Page 65: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/65.jpg)
jQuery.fn.extend({
check: function() {
return this.each(function() {
this.checked = true; });
},
uncheck: function() {
return this.each(function() {
this.checked = false; });
}
});
![Page 66: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/66.jpg)
jQuery UI (ou “porque uma imagem vale mais que mil palavras”)
![Page 67: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/67.jpg)
![Page 68: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/68.jpg)
Draggables Droppables Sortables Selectables Resizables
![Page 69: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/69.jpg)
Accordion Datepicker Dialog Slider Tabs
![Page 70: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/70.jpg)
Blind Clip Drop Explode Fold Puff Slide Scale Size Pulsate Bounce Highlight Shake Transfer
![Page 71: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/71.jpg)
Se eles conseguiram, você também pode...
![Page 72: JavaScript ninja com jQuery](https://reader033.fdocument.pub/reader033/viewer/2022051412/54bd18e84a7959f95e8b45e4/html5/thumbnails/72.jpg)
(Hi-Yaaaaaaaaaaa...)
Reinaldo de Souza [email protected]
< http://reinaldojunior.net >
Dúvidas? Comentários? Reclamações? Sugestões?Piadinhas sem graça?
O-bri-ga-do