Neste tutorial você vai aprender a criar um menu que se expande usando jQuery.
Preview Online
Baixar Arquivos
Em primeiro lugar devemos criar a estrutura necessária para que nosso aplicativo possa viver. Para isso criei um arquivo chamado expand.html, que será responsável pela estruturação do código, um arquivo chamando expand.css, que será responsável pelo visual de uma maneira geral, e um arquivo chamado expand.js, que será responsável pelos efeitos, além da pasta com as imagens que serão usadas no menu.
Começando pelo começo, nada é mais importante que o arquivo HTML, então vamos à ele.
a estrutura básica para iniciar o projeto é vista a seguir (repare como o framework jQuery já está carregado através da tag script):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>expandindo menu com jQuery</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> </head> <body> </body> </html>
Em seguida precisaremos de uma lista, onde cada item representará um item do menu.
dentro de cada item teremos uma imagem, um título e uma descrição.
<ul id="expand"> <li> <img src="drupal.jpg" alt="" width="80" height="80" /> <h2>Drupal</h2> <p>Drupal is a free and open source[1] Content Management System (CMS) written in PHP. It is used as a back-end system for many different types of websites, ranging from small personal blogs to large corporate and political sites. It is distributed under the GNU GPL.</p> </li> <li> <img src="expressionengine.jpg" alt="" width="80" height="80" /> <h2>Expression Engine</h2> <p>EllisLab is a software developer based in Bend, Oregon which develops applications written in PHP. The company is privately owned and has to date accepted no venture capital funding of any kind. Since the company's founding in January 2002.</p> </li> <li> <img src="frog.jpg" alt="" width="80" height="80" /> <h2>Frog CMS</h2> <p>Frog CMS is an open source content management system originally developed by the company Philippe Archambault. The design decision taken from its start was to use PHP5 as the language for the software, along with a MySQL database backend, although it also has support for SQLite (version 3). It is a port of the Ruby on Rails CMS known as Radiant, although Frog has begun to take its own development direction.</p> </li> <li> <img src="joomla.jpg" alt="" width="80" height="80" /> <h2>Joomla!</h2> <p>Joomla! is a content management system platform for publishing content on the World Wide Web and intranets as well as a Model-view-controller (MVC) Web Application Development framework. The system includes features such as page caching to improve performance, RSS feeds, printable versions of pages, news flashes, blogs, polls, website searching, and language internationalization. It is written in the PHP programming language and uses the MySQL database system to store information. Joomla is the result of a fork of Mambo. Released under the terms of the GNU General Public License, Joomla is free software.</p> </li> <li> <img src="magento.jpg" alt="" width="80" height="80" /> <h2>Magento</h2> <p>Magento is an Open Source ecommerce web application launched on March 31, 2008. It was created by Varien, building on components of the Zend Framework. Magento is available under the Open Software License version 3.0. Since version 1.1.7 some parts are licensed under the Academic Free License version 3.0. Magento Enterprise Edition, a paid for version of Magento aimed at larger companies, was launched on April 15, 2009.</p> </li> <li> <img src="modx.jpg" alt="" width="80" height="80" /> <h2>MODx</h2> <p>MODx is a free, open source content management system and web application framework for publishing content on the world wide web and intranets. MODx is licensed under the GPL. MODx is written in the PHP programming language and uses the MySQL database.</p> </li> </ul>
Feito isso devemos estilizar nosso trabalho, então é hora de visitar o arquivo expand.css.
as instruções linha a linha são a seguinte:
*{margin:0;padding:0;list-style:none;}
div{overflow:hidden; width:450px;}
html{background:#ccc;}
#expand li{float:left;width:390px;height:170px;margin:2px;overflow:hidden;border:1px solid #555;-moz-border-radius:10px;-webkit-border-radius:10px;}
#expand img{border:3px solid #686;background: #aaa;padding:3px;float:left;margin:3px 5px;}
#expand p{font:normal normal normal 11px/1.4 arial,sans-serif;float:none;padding:3px 12px 0 5px;margin:5px 0 0 102px;}
#expand h2{font:bold italic normal 15px/1 georgia,serif;margin:3px 0 0 108px;}
#expand li:nth-child(even){background: #dff;}
#expand li:nth-child(odd){background: #fdf;}
Repare que as duas últimas linhas são formadas por propriedades presentes somente em CSS3, mas são reconhecidas em todos os navegadores modernos (ou seja, Firefox, Safari, Chrome e Opera). Por último devemos criar o efeito usando jQuery. Abrindo arquivo expand.js, o primeiro que devemos fazer é iniciar o jQuery.
$(document).ready(function(){
});
O segundo passo é criar uma div que vai envolver todo o conteúdo dos itens. Esta parte é importante para que o texto não flua quando o item expandir e retrair.
$('#expand li').wrapInner('<div>');
Em seguida usamos jQuery para diminuir todos os itens, e mostrar somente a imagem.
$('#expand li').css({
width: '102px'
,height: '100px'
});
Cada item tem uma altura diferente, e para podermos expandir uma altura suficiente para mostrar todo o conteúdo devemos primeiro conhecer a altura do maior deles, então um loop é criado para rodar todos as divs e pegar a maior altura encontrada
var alturaMax = 100;
$('#expand li div').each(function(){
alturaDiv = $(this).height();
if(alturaDiv > alturaMax){
alturaMax = alturaDiv;
}
});
A seguir vem a animação em si
$('#expand li').hover(/*mouse em cima*/,/*mouse saindo*/);
Quando o mouse estiver em cima, queremos expandir o item para 450px de largura e para a altura do maior dos itens, mas somente depois de parar o que estava fazendo.
$('#expand li').hover(function(){
$(this).stop().animate({
width: '450px'
,height: alturaMax + 5 + 'px'
});
},/*mouse saindo*/);
Quando o mouse deixa o item, queremos que o mesmo pare o que estiver fazendo e volte a animar retornando à posição inicial
$('#expand li').hover(function(){
$(this).stop().animate({
width: '450px'
,height: alturaMax + 5 + 'px'
});
},function(){
$(this).stop().animate({
width: '102px'
,height: '100px'
});
});
Nesse ponto o script já funciona e faz exatamente o que queremos, mas bons programadores sempre retornam ao seu código e tentam o tornar melhor. O arquivo criado, apesar de funcionar, apresentam um monte de más práticas quando se diz respeito a javascript, e a seguir tentaremos contornar esses problemas.
A primeira parte que devemos notar é que o seguinte fragmento do código é chamada inúmeras vezes
$('#expand li')
Chamadas por elementos do DOM são demasiadamente penosas em javascript, e como fazemos estas chamadas várias vezes usando jQuery, nosso script acaba se tornando bastante lento. Para solucionar este problema devemos armazenar todos as chamadas em cache, mas só faz sentido fazer isso caso esta chamada seja feita mais de uma vez. O mesmo deve ser feito com a variável $(this), porém nesse caso elas são chamadas somente uma vez em cada loop, então não se deve tocar nelas. Corrigindo este problema, nosso código fica da seguinte maneira
$(document).ready(function(){
var $item = $('#expand li');
$item.wrapInner('<div>');
$item.css({
width: '102px'
,height: '100px'
});
var alturaMax = 100;
$item.children('div').each(function(){
alturaDiv = $(this).height();
if(alturaDiv > alturaMax){
alturaMax = alturaDiv;
}
});
$item.hover(function(){
$(this).stop().animate({
width: '450px'
,height: alturaMax + 5 + 'px'
});
},function(){
$(this).stop().animate({
width: '102px'
,height: '100px'
});
});
});
Um passo adicional que podemos tomar é usar o que é conhecido em javascript como chaining. Isto significa aplicar seguidas funções sem sair de um contexto. Talvez fique mais claro no código abaixo
$(document).ready(function(){
var $item = $('#expand li');
var alturaMax = 100;
$item.wrapInner('<div>')
.css({
width: '102px'
,height: '100px'
})//não se usa ';' aqui, para que os métodos possam ser acorrentados
.children('div').each(function(){
alturaDiv = $(this).height();
if(alturaDiv > alturaMax){
alturaMax = alturaDiv;
}
})//não se usa ';' aqui, para que os métodos possam ser acorrentados
.hover(function(){
$(this).stop().animate({
width: '450px'
,height: alturaMax + 5 + 'px'
});
},function(){
$(this).stop().animate({
width: '102px'
,height: '100px'
});
});
});
Neste momento o script já está bem mais rápido, e agora podemos criar mais um efeito onde a altura do item será animado o suficiente para mostrar todo o seu conteúdo, então se o item tiver pouco conteúdo a sua altura expandirá pouco ou não expandirá, e caso o item tenha bastante conteúdo a sua altura expandirá o necessário para que mostre todo o texto.
Para este efeito devemos descobrir a altura da div quando passamos o mouse por cima do item (repare que comentei o código que não será mais usado e modifiquei a variável que dá a altura do item da lista) .
$(document).ready(function(){
var $item = $('#expand li');
var alturaMax = 100,altura;
$item.wrapInner('<div>')
.css({
width: '102px'
,height: '100px'
})//não se usa ';' aqui, para que os métodos possam ser acorrentados
// .children('div').each(function(){
// alturaDiv = $(this).height();
// if(alturaDiv > alturaMax){
// alturaMax = alturaDiv;
// }
// })
.hover(function(){
altura = $(this).children('div').height();
$(this).stop().animate({
width: '450px'
,height: altura + 5 + 'px'
});
},function(){
$(this).stop().animate({
width: '102px'
,height: '100px'
});
});
});
Abaixo está o conteúdo de todos os arquivos criados.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>sem t&amp;amp;amp;amp;amp;amp;amp;amp;amp;iacute;tulo</title> <link type="text/css" href="expand.css" rel="stylesheet"/> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> <script type="text/javascript" src="expand.js"></script> </head> <body> <ul id="expand"> <li> <img src="imagens/drupal.jpg" alt="" width="80" height="80" /> <h2>Drupal</h2> <p>Drupal is a free and open source[1] Content Management System (CMS) written in PHP. It is used as a back-end system for many different types of websites, ranging from small personal blogs to large corporate and political sites. It is distributed under the GNU GPL.</p> </li> <li> <img src="imagens/expressionengine.jpg" alt="" width="80" height="80" /> <h2>Expression Engine</h2> <p>EllisLab is a software developer based in Bend, Oregon which develops applications written in PHP. The company is privately owned and has to date accepted no venture capital funding of any kind. Since the company's founding in January 2002.</p> </li> <li> <img src="imagens/frog.jpg" alt="" width="80" height="80" /> <h2>Frog CMS</h2> <p>Frog CMS is an open source content management system originally developed by the company Philippe Archambault. The design decision taken from its start was to use PHP5 as the language for the software, along with a MySQL database backend, although it also has support for SQLite (version 3). It is a port of the Ruby on Rails CMS known as Radiant, although Frog has begun to take its own development direction.</p> </li> <li> <img src="imagens/joomla.jpg" alt="" width="80" height="80" /> <h2>Joomla!</h2> <p>Joomla! is a content management system platform for publishing content on the World Wide Web and intranets as well as a Model-view-controller (MVC) Web Application Development framework. The system includes features such as page caching to improve performance, RSS feeds, printable versions of pages, news flashes, blogs, polls, website searching, and language internationalization. It is written in the PHP programming language and uses the MySQL database system to store information. Joomla is the result of a fork of Mambo. Released under the terms of the GNU General Public License, Joomla is free software.</p> </li> <li> <img src="imagens/magento.jpg" alt="" width="80" height="80" /> <h2>Magento</h2> <p>Magento is an Open Source ecommerce web application launched on March 31, 2008. It was created by Varien, building on components of the Zend Framework. Magento is available under the Open Software License version 3.0. Since version 1.1.7 some parts are licensed under the Academic Free License version 3.0. Magento Enterprise Edition, a paid for version of Magento aimed at larger companies, was launched on April 15, 2009.</p> </li> <li> <img src="imagens/modx.jpg" alt="" width="80" height="80" /> <h2>MODx</h2> <p>MODx is a free, open source content management system and web application framework for publishing content on the world wide web and intranets.</p> </li> </ul> </body> </html>
*{margin:0;padding:0;list-style:none;}
div{overflow:hidden; width:450px;}
html{background:#ccc;}
#expand li{float:left;width:390px;height:220px;margin:2px;overflow:hidden;border:1px solid #555;-moz-border-radius:10px;-webkit-border-radius:10px;}
#expand img{border:3px solid #686;background: #aaa;padding:3px;float:left;margin:3px 5px;}
#expand p{font: normal normal normal 11px/1.4 arial,sans-serif;padding:3px 12px 0 5px;margin:5px 0 0 102px;}
#expand h2{font:bold italic normal 15px/1 georgia,serif;margin:3px 0 0 108px;}
#expand li:nth-child(even){background: #dff;}
#expand li:nth-child(odd){background: #fdf;}
/**
* @author http://tutorial-city.net/
*/
$(document).ready(function(){
var $item = $('#expand li');
var alturaMax = 100;
$item.wrapInner('<div>')
.css({
width: '102px'
,height: '100px'
})
.hover(function(){
altura = $(this).children('div').height();
$(this).stop().animate({
width: '450px'
,height: altura + 5 + 'px'
});
},function(){
$(this).stop().animate({
width: '102px'
,height: '100px'
});
});
});
O resultado final pode ser visualizado no link abaixo.
Preview Online
Baixar Arquivos
Espero que tenha aprendido bastante com este tutorial, e sinta-se à vontade para comentar e acrescentar ao que foi passado. Abraços e até a próxima!
18 Comentários para “Criando menu expansível com jQuery”
7 de setembro de 2009, segunda-feira às 13:49
Muito show a vídeo aula e tbm o tutorial. Uma das coisas q gosto do jquery é a possibilidade da concatenação de efeitos, eventos, etc. As dicas q ia colocar, vc já fez as alterações no posts, rs.
abrs
7 de setembro de 2009, segunda-feira às 14:55
@David CHC
Chaining realmente é algo poderosíssimo em jQuery, e também é recomendado, pois reduz o número de vezes que você chama uma variável, além de deixar o código um bocado mais limpo.
A idéia era essa mesma, o vídeo serve pra dar uma visão geral e fazer a coisa funcionar, já o tutorial escrito vai além e mostra como fazer as coisas de uma forma mais inteligente ou mais completa, depende do tutorial, nesse caso estendi das 2 maneiras
7 de setembro de 2009, segunda-feira às 17:24
Que isso hem…
Parabéns ficou um ótimo efeito!
8 de setembro de 2009, terça-feira às 11:36
Meus parabéns pelo tutorial!
Muito Bom!
Se você conseguir, ou estou precisando do efeito menu Dock, igual aqueles que tem no sistema operacional Apple.
Tem esse efeito no site do MX Masters: http://www.mxmasters.com.br/
8 de setembro de 2009, terça-feira às 11:56
O efeito é show!!
Parabéns…
8 de setembro de 2009, terça-feira às 16:16
@Henrique Mezzomo
Existem vários plugins que fazem esse efeito. Eu recomendo o Fisheye e o CSS Dock Menu
9 de setembro de 2009, quarta-feira às 14:48
muito show, parabéns pela iniciativa, continue partilhando seu conhecimento, obrigado
9 de setembro de 2009, quarta-feira às 23:16
Muito bom o conteúdo do site. Parabéns mesmo! Conheci o site pelo Vídeo Aulas Brasil e já favoritei aqui!
Abração e continue com o ótimo trabalho!
12 de setembro de 2009, sábado às 19:58
Parabéns mais uma bela aula! belo tutorial e belo trabalho continue assim…aproveitando a oportunidade gostaria de “pedir” óbviamente se estiver ao seu alcançe e se puder realiza-lo.
Gostaria que você fizesse uma video aula enviando formulário para e-mail com php…eu já vi muitas videos aulas inclusive na VAB mas ainda não chegou onde eu precisava ainda não estou confiante. se puder agradeceria muito! Obrigado!
13 de setembro de 2009, domingo às 13:33
@Diogo Lopes
Sim Diogo, posso fazer. Até tive uma ideia de como estender isso aí. Fique ligado por que em breve pode sair um tutorial bem legal sobre isso.
Não esquece de assinar aos feeds pra ser notificado quando sair
Abraços
13 de setembro de 2009, domingo às 21:12
Oba, que bom! estarei esperando já assinei o feeds, e gostaria de lhe pedir uma coisa a mais! se não for demais claro!
Quando criar a video aula cria ao menos um campo a mais do que são usados nas videos aulas comuns, se possivel ainda com botãos do tipo radio!
Obrigado novamente! até mais!
Abraços!
27 de setembro de 2009, domingo às 23:03
Tenho acompanhado o site desde o inicio, e ele tem me motivado a ser um desenvolvedor Web.
Parabens, otimos tutoriais e dicas…
18 de outubro de 2009, domingo às 1:19
Boa noite
Parabéns pela iniciatica, sua explicação é excelente, parabéns mesmo.
Porém ,nao consigo de maneira nenhuma executar este código no VS2008, ao startar o projeto de cara apresenta o erro de ” Erro em tempo de execução do Microsoft JScript: Objeto esperado “, sem nenhum código de erro adicional. Este erro pode ser com o Javascript/VS2008, alguma configuração?
Desde já agradeço.
18 de outubro de 2009, domingo às 4:21
@Wagner
VS2008 = Visual Studio 2008?
Eu nunca usei essa IDE, então não faço ideia de como ela interpreta o javascript. Talvez o problema seja que ela está tentando interpretar o código sem saber que ele é uma extensão do jQuery, e só funciona se o mesmo estiver presente, caso contrário vários objetos realmente não vão existir. Não sei como você pode configurar o VS pra debugar assim, mas acredito que o problema seja esse.
Abraços
18 de outubro de 2009, domingo às 21:15
Consegui, agora deu certo.
Eu copiei seu código e colei diretamente no projeto (apesar de ter feito apenas as primeiras 5 linhas do Js e ter certeza q estava correto rsrs )e também mudei a posição da tag script que fazia referencia ao jquery para antes da tag do arquivo expand.js . Nao sei qual das duas foi a mudança apropriada, mas deu certo, obrigado.
20 de outubro de 2009, terça-feira às 9:21
@Wagner
O link pro jQuery sempre tem de vir antes dos outros arquivos que contenham jQuery. Isso acontece por que os arquivos são executados na ordem que são baixados, então você só pode criar algo em jQuery depois de baixar o framework.
Abraços
3 de novembro de 2009, terça-feira às 1:07
Muito legal mesmo, to correndo atras deste afeito e achei o resultado muito legal, congratulations
3 de fevereiro de 2010, quarta-feira às 18:57
Muito bom tutorial!
aprendo muito com vocês…muito obrigado mesmo!
abraços
Deixe seu comentário!