Bem pessoas, o fato qual me levou a desenvolver este menu foi a necessidade de manter um controle no mesmo, podendo fechar e abrir o mesmo item do submenu, tudo isso usando ul li, direto ao ponto.
Primeira coisa a fazer, como verificar qual menu estava aberto antes do reload?
A solução para isso foi gravar o menu em cookie para verificação, segue abaixo as funções para criar e recuperar o cookie.
Função para recuperar o cookie:
/** * Retorna o valor do cookie * @autor Deusimar Ferreira * @param string name */ getCookie = function(Name){ var re=new RegExp(Name+"=[^;]+", "i"); if (document.cookie.match(re)) return document.cookie.match(re)[0].split("=")[1]; return null; }
Função para criar e setar o valor do cookie:
/** * Define cookie * @autor Deusimar Ferreira * @param string name * @param string|int value */ setCookie = function(name, value){ document.cookie = name + "=" + value; }
Cirei um atributo para meu submenu chamado de menuIndex.
// Pega submenus var subContents = $('#menu li ul'); // Percorre o menu e adiciona indice $("#menu li div a").each(function(index) { subContents.eq(index).attr({menuIndex: index + 'c'}); })
Este script contém os eventos accordion do menu, ele faz a verificação de qual submenu esta aberto e chama o evento, caso o item clicado esteja aberto ele será fechado ou inverso, caso seja outro item ele abre o item clicado e fecha os outros itens.
$("div a").click(function() { //$("#menu li ul:visible").slideUp("slow"); // Esocnde menu item que visivel //$(this).parent().next().slideToggle("slow"); // Mostra o menu item que recebeu o evento click // Criar objeto gobal do parent span a var _this = $(this).parent().next(); // Percorre o menu para verificar as ações que deve ser executada // Verifica qual submenu deve ser fechado e qual será aberto $("div a").each(function(index){ if ($('#menu li ul:eq(' + index + ')').attr('menuIndex') != _this.attr('menuIndex')) { // Verifica se exite algum submenu que não seja o que recebeu o evento do click aberto if ($('#menu li ul:eq(' + index + ')').is(':visible')) $('#menu li ul:eq(' + index + ')').slideUp("slow"); // Esocnde submenu item que visivel } else { (_this.is(':visible')) ? _this.slideUp("slow") // Esocnde submenu item que visivel : _this.slideDown("slow"); // Mostra o submenu item que recebeu o evento click } }) // Retorna falso funciona como um pause return false; })
Neste outro script ao fechar a página ele recuperar o índice do menu e cria um cookie com seu valor.
// Evento window unload $(window).bind('unload', function(){ $('#menu li ul').unbind(); // Remove eventos var expandeIndices = []; // Array indice $("#menu li ul:visible").each(function(index){ // Insere o valor do menuindex no array expandeIndices.push($(this).attr('menuIndex')); }) expandeIndices = (expandeIndices.length == 0) ? '-1c' : expandeIndices; setCookie('menuIndex', expandeIndices); // Seta o cookie e seu respectivo valor })
Pega o valor do cookie e mantém o respectivo submenu aberto.
// Verifica o cookie para ver qual submenu deve ser mostrado $("#menu li ul").each(function(){ // Mostra o submenu if ($(this).attr('menuIndex') == getCookie('menuIndex')) { $(this).show(); } else { // Esconde o restante $(this).hide(); } })
Eis o script completo:
$(document).ready(function() { /** * Retorna o valor do cookie * @autor Deusimar Ferreira * @param string name */ getCookie = function(Name){ var re=new RegExp(Name+"=[^;]+", "i"); if (document.cookie.match(re)) return document.cookie.match(re)[0].split("=")[1]; return null; } /** * Define cookie * @autor Deusimar Ferreira * @param string name * @param string|int value */ setCookie = function(name, value){ document.cookie = name + "=" + value; } /** * Accordion Menu * @autor Deusimar Ferreira * @param #menu li ul * @param #menu li div a */ if (typeof expandeIndices == 'string') expandeIndices = expandeIndices.replace(/c/ig, '').split(',') // Transfoma string value em array (ie: "c1,c2,c3" becomes [1,2,3] // Pega submenus var subContents = $('#menu li ul'); // Percorre o menu e adiciona indice $("#menu li div a").each(function(index) { subContents.eq(index).attr({menuIndex: index + 'c'}); }) // Apresenta apenas o primeiro menu list $('#menu li ul:not(:first)').hide(); $("div a").click(function() { //$("#menu li ul:visible").slideUp("slow"); // Esocnde menu item que visivel //$(this).parent().next().slideToggle("slow"); // Mostra o menu item que recebeu o evento click // Criar objeto gobal do parent span a var _this = $(this).parent().next(); // Percorre o menu para verificar as ações que deve ser executada // Verifica qual submenu deve ser fechado e qual será aberto $("div a").each(function(index){ if ($('#menu li ul:eq(' + index + ')').attr('menuIndex') != _this.attr('menuIndex')) { // Verifica se exite algum submenu que não seja o que recebeu o evento do click aberto if ($('#menu li ul:eq(' + index + ')').is(':visible')) $('#menu li ul:eq(' + index + ')').slideUp("slow"); // Esocnde submenu item que visivel } else { (_this.is(':visible')) ? _this.slideUp("slow") // Esocnde submenu item que visivel : _this.slideDown("slow"); // Mostra o submenu item que recebeu o evento click } }) // Retorna falso funciona como um pause return false; }) // Evento window unload $(window).bind('unload', function(){ $('#menu li ul').unbind(); // Remove eventos var expandeIndices = []; // Array indice $("#menu li ul:visible").each(function(index){ // Insere o valor do menuindex no array expandeIndices.push($(this).attr('menuIndex')); }) expandeIndices = (expandeIndices.length == 0) ? '-1c' : expandeIndices; setCookie('menuIndex', expandeIndices); // Seta o cookie e seu respectivo valor }) // Verifica o cookie para ver qual submenu deve ser mostrado $("#menu li ul").each(function(){ if ($(this).attr('menuIndex') == getCookie('menuIndex')) { // Mostra o submenu $(this).show(); } else { // Esconde o restante $(this).hide(); } }) })
Folha de estilo css:
div { font-family: Verdana, Arial; font-size: 11px; font-weight: bold; margin: 1px 0px; padding: 0px; border: 1px #06c solid; background-color: gray; } ul { list-style-type: none; max-width: 202px; _width: 200px; /* Adivinha para quem serve essa linha - Claro que é o IE! */ } #menu li { margin: 0px 0px; } #menu li ul{ margin: 0px; padding: 1px 5px; display: none; } #menu li div a{ text-decoration: none; outline: none; line-height: 18px; padding: 1px 4px; color: white; } a { font-family: Verdana, Arial; font-size: 11px; text-decoration: none; outline: none; padding: 1px 4px; color: #06c; } a:hover { font-family: Verdana, Arial; font-size: 11px; text-decoration: underline; outline: none; padding: 1px 4px; color: #06c; }
Estrutura do menu em lista não ordenada, ul li:
<ul id="menu"> <li> <div><a href="">JQuery Documentation</a></div> <ul id="submenu"> <li><a href="http://docs.jquery.com/Main_Page" target="blank" title="Documentation">Documentation</a></li> <li><a href="http://docs.jquery.com/Tutorials" target="blank" title="Tutrorials">Tutrorials</a></li> </ul> </li> <li> <div><a href="">Player Game</a></div> <ul id="submenu"> <li><a href="http://www.cdt.unb.br/memoria" title="Memória Empreendedora">Memória Empreendedora</a></li> <li><a href="" title="Memória Empreendedora">Memória Empreendedora</a></li> </ul> </li> <li> <div><a href="">Sobre</a></div> <ul id="submenu" style="border-bottom: 1px #06c solid;"> <li><a href="https://zimar.wordpress.com/about/" title="Sobre Me">Sobre Me</a></li> <li><a href="http://docs.google.com/View?docid=ddft82q4_42hmpmmcgv" title="Curriculum">By Curriculum</a></li> </ul> </li> </ul>
é isso ai, qualquer dúvida, pergunte!
Tem como fazer isso funcionar para as categorias com as subcategorias do WordPress? Tentei de tudo quanto é jeito e não consegui. Procurei plugins e encontrei pouca coisa mas nenhum q funcione, queria somente para fazer o accordion nas categorias e subcategorias…
Vlw!
Qual a versão do wordpress você esta usando, até o momento não tinha testado no wordpress, vou fazer um exemplo para ver como que funfa, depois posto o resultado aqui.
mto obrigado pela participação, t+.
Opa, parabens pelo artigo.
Cara, eu tava querendo fazer uma modificação para uma adequação ao wordpress e não to conseguindo achar as alterações necessárias no código.
Como eu faço para usar o para separar quem é menu e submenu no código do jQuery?
Seria isso ?
var subContents = $(‘#submenu ul’);
$(“#menu li div a”).each(function(index) {
subContents.eq(index).attr({menuIndex: index + ‘c’});
})
To na dúvida…
Abs
Olá, Ricardo,
Vc esta querendo serpar o menu do submenu ou apenas pegar os submenus, para pegar o submenu estou utilizando o código abaixo.
// Pega submenus
var subContents = $(‘#menu li ul’);
Também tenho a mesma dúvida do Marcelo.
Mas fora esta sabe me dizer como faço um menu horizontal que fique marcado na categoria escolhida?
Boa tarde, João,
Para o menu horizontal lhe recomendo utilizar o método $.tabs() do JQuery, dê uma olhada nos links abaixo.
http://docs.jquery.com/UI/Tabs
http://www.gmarwaha.com/blog/?p=7
opa zimar, valeu!
então, surgiu outra dúvida:
como eu faço pra ativar os links nos indices? tem como?
até então ele só faz abrir e fechar os submenus né?
seria mexer no $(“div a”).click(function() ?
abs
🙂
Realmente não tem este tratamento, mais segue uma sugestão para vc tentar resolver, seguite no href do indice vc insere o link que deseja abrir e dentro do método $( “div a” ).each(function(index) {} ) você faz algo como window.location = $( “div a” ).attr( “href” );
Ex:
$( “div a” ).click( function() {
$(“div a”).each(function(index){
…
window.location = $( “div a” ).attr( “href” )
}
} )
Ou você também pode retirar o return false; do método $( “div a” ).click( function() {} ).
abs!
Esse menu aiu como uma luva para um projeto que estava atrasado e não tinha-se tempo de bolar um desses.
Voilá
Teria como criar mais um submenu?
A estrutura seria
– Menu
*-links
– Submenu
*-links
– Submenu 2
*-links
Eu tenteii mais não consegui!
Olá, David,
é possivel criar esta estrutura, mais será necessario repensar toda estrutura do menu.
Você tem interessem em nos ensinar???
Obrigado
Olá, David,
no momento estou sem tempo para lhes ensinar, provavelmente só vou conseguir depois do mês de setembo.
mais por enquando, lhe recomendo dar uma olhada na documentação do JQuery.
Olá Zimar… gostaria de tirar uma dúvida de principiante… to usando o seu menú e tá funcionando direitinho… mas gostaria de usá-lo da mesma forma q o colega disse um pouco acima… com o link no índice. Tentei praticar a sua sugestão mas não conseguí… tem como vc colocar o script já com a inserção q vc citou? Obrigado…
Fala Paulo, blz,
Puts, tá hospitalizado por alguns dias, mais já estou desenvolvendo um exemplo de submenu com link, assim que finalizar posto aqui.
abçs!
Bem pessoal, segue a solução.
Primeiro: Faça um pequeno ajuste no js, coloque o bloco da linha 49 à 63 dentro de um verificador, segue exemplo abaixo.
Segundo: Para inserir link no menu basta alterar a estrutura da lista removendo o ul “submenu”, observe o exemplo abaixo.
abrçs, espero ter ajudado, qualquer dúvida, tó por aqui!