jQuery Mobile - Navegação por Abas

Este é um dos muitos exemplos de jQuery Mobile. por favor consulte os artigos de introdução ao jQuery Mobile e ao jQuery para informações introdutórias sobre os frameworks.

O código fonte deste exemplo pode ser encontrado aqui: https://github.com/gomobile/sample-jqm-tab-nav.

    

Este exemplo é um esqueleto multi-páginas para navegação basea em abas. Para outros estilos de navegação, por favor consulte os exemplos de navegação baseada em lista e do tipo springboard.

Adicionalmente, este exemplo demonstra como criar um widget de menu de opções que mantém o seu estado através das transições de página, e como injetar dinamicamente widgets no DOM.

Navegação Baseada em Abas

A página principal apresenta abas de páginas para a navegação. Isto é implementado usando um navbar do jQuery Mobile, que é uma barra com a largura da página composta por 1 a 5 botões de mesma largura dispostos em linha. O navbar é representado como uma lista HTML não ordenada encapsulada em um container div com o atributo data-role="navbar". Cada item da lista contém um link para a página de destino, e um texto correspondete para ser apresentado. O item de lista representando a página atualmente visualizada é aplicado com uma classe ui-btn-active para destacar a aba correspondente como a cor de estado ativo, e uma classe ui-state-persist para que o estado ativo seja restaurado cada vez que se navegue de volta para esta página. O navbar é constituído por um rodapé fixo e persistente, que permanece no lugar quando é feito o deslocamento e a navegação entre as páginas. Este rorapé é mantido visível durante todo o tempo, sobrescrevendo o comportamento padrão tapToggle do jQuery Mobile, que oculta e mostra o rodapé cada vez que a tela é tocada. (Na prática, o comportamento padrão tapToggle quase sempre resulta em um navbar que desaparece quando se tenta trocar de aba em um dispositivo móvel.)

 
<div data-role="footer" data-id="tabnav-footer" data-position="fixed"> <div data-role="navbar"> <ul> <li><a href="#home" class="ui-btn-active ui-state-persist">One</a></li> <li><a href="#page2">Two</a></li> <li><a href="#page3">Three</a></li> </ul> </div> </div> 
 
/* manter o rodapé visível todo o tempo */ $(':jqmData(role=footer)').fixedtoolbar( { tapToggle: false } ); 

Opções Personalizadas do Widget de Menu

Este exemplo apresenta um widget de menu com opções personalizadas baseado no elemento de formulário checkboxes do jQuery Mobile. Para obter uma aparência compacta no menu drop-down, o atributo data-role="controlgroup" do jQuery Mobile é usado para agrupar os checkboxes sem espaçamento extra entre eles, o atributo data-mini="true" é usado para especificar um estilo comprimido com fontes menores e um CSS personalizado é usado para limitar a largura em 120px. O menu de opções é posicionado no canto superior direito da área interna da view, bem abaixo da barra de ferramentas de cabeçalho posicionada de forma fixa, usada para exibir e ocultar o menu. O posicionamento vertical do menu é dinamicamente determinado, depois que a altura do cabeçalho e o posicionamento da área de conteúdo foram determinados pelo processo de runtime de layout do HTML5.

 
<div class="optionsMenu"> <form action="#" method="get"> <div data-role="fieldcontain"> <fieldset data-role="controlgroup" data-mini="true"> <input type="checkbox" name="option1" id="option1"/> <label for="option1">Option 1</label> <input type="checkbox" name="option2" id="option2"/> <label for="option2">Option 2</label> : </fieldset> </div> </form> </div>
 
/* estilo personalizado do menu de opções (posição & largura) */ .optionsMenu { /* largura estreita personalizada para se parecer com um menu */ width: 120px; /* canto superior direito abaixo do botão de opções (1px de margem, setado no topo dinamicamente) */ position: fixed; right: 1px; }

 

/* calcular a posição vertical do menu */
initPosition: function($page) {
    /* o menu deve ser alinhado ao máximo com a área de conteúdo no topo (espaço de 1px) */
    top = $page.find(':jqmData(role=content)').position().top + 1;
    /* atualizar a posição para o widget de menu da página atual */
    $page.find('.optionsMenu').css('top', top);
}

Criação á partir de um Modelo

Como o jQuery Mobile não permite nativamente que widgets persistam através de diversas páginas (com excessão aos cabeçalhos e rodapés persistentes), este exemplo cria um widget de menu de opções por página. Ao invés de replicar o mesmo código HTML de widget para cada página, o widget é especificado uma vez em um modelo HTML, e então copiado e inserido dinamicamente em cada página. Isso permite que o código fique mais legível e seja mantido com maior facilidade, deixando menor espaço para erros de copiar e colar. O modelo é embarcado dentro do código HTML principal como uma tag de script do tipo desconhecido "text/html". Isso permite que o modelo seja formatado e mantido com o resto do código HTML, enquanto fica invisível para o runtime HTML5 e acessível ao código JavaScript*. Uma vez criado e inserido dentro do DOM, o widget dispara seu evento create para informar ao jQuery Mobile de sua existência, para que possa ser inicializado com o estilo e comportamento apropriados do jQuery Mobile. 

 
<!-- modelo do menu de opções (oculto em uma tag de script desconhecida) --> <script type="text/html" id="optionsMenuTmpl"> <div class="optionsMenu"> <!-- veja acima --> </div> </script>
 
/* cria um menu de opções por página */ function($page) { /* copia o código HTML do menu de opções do modelo */ $($('#optionsMenuTmpl').html()) /* insere no DOM */ .prependTo($page.find($(':jqmData(role=content)'))) /* faz com que o jQuery Mobile processe o widget */ .trigger('create') }

Mantendo o Estado Através das Páginas

Para manter a ilusção de que todos os widgets do menu de opcões são exatamente o mesmo, o estado do checkbox é mantido consistente através dos widgets das diferentes páginas. Este exemplo utiliza uma matriz, options, para sincronizar de forma leve o estado do checkbox através de cada transição de página. Antes de deixar a página atual (ex. o disparo do evento pagebeforehide), o exemplo grava o estado de cada checkbox na matriz options. Antes de entrar em uma nova página (ex. o disparo do evento pagebeforeshow), o exemplo atualiza o estado de cada checkbox com o conteúdo da matriz options, e então informa ao jQuery Mobile através do checkboxradio('refresh') para aplicar o estilo ao novo estado atualizado.

 
/* estado das quatro opções para ser sincronizado através das  transições de páginas (todos inicializados como não selecionados) */ options: [false, false, false, false] 
 
/* grava o estado das opções (antes de deixar a página atual) */ saveState: function($optionsMenu) { $optionsMenu.find('input') .each(function(index) { options[index] = $(this).is(':checked'); }); }

 

/* atualiza as opções como o último estado (antes de entrar em uma nova página) */
reconcileState: function($optionsMenu) {
    $optionsMenu.find('input')
        .each(function(index) {
            /* desenha as marcas de checagem para as opções selecionadas */
            if (options[index]) {
                $(this).attr('checked', true).checkboxradio('refresh');
            }
            /* limpa as marcas de checagem para as opções não selecionadas */

            else {
                $(this).attr('checked', false).checkboxradio('refresh');
            }
        });
}

Açoes Baseadas em Eventos

O menu de opções atua como um menu drop-down para o botão de opções na barra de ferramentas do cabeçalho. O menu é mostrado quando o botão é pressionado, e ocultado quando o botão for pressionado novamente. O menu e o botão não sabem da existência um do outro, para estabelecer uma separação clara das preocupações. Em vez disso, eles se comunicam de uma dissociada através do canal global $.event do jQuery. O botão dispara um evento personalizado toggleOptionsMenu quando é pressionado. O menu para a página atual subscreve ao evento toggleOptionsMenu, e ajusta sua própria visibilidade depois que receber o evento.

 
/* botão na barra de ferramentas de cabeçalho clicado */ $optionsBtn.on('click', function() { $.event.trigger('toggleOptionsMenu'); });
 
/* o menu de opções para a página atual subscreve ao evento toggle */ $optionsMenu.on('toggleOptionsMenu', function() { if ($(this).is(':visible')) { $(this).hide(); } else { $(this).show(); } });

Configurando os Padrões do jQuery Mobile

Tão logo esteja carregado, o jQuery Mobile dispara o evento mobileinit no objeto document, e então ele automaticamente aplica diversos aprimoramentos no markup. Sendo assim, para sobrescrever os padrões do jQuery Mobile antes que estes aprimoramentos ocorram, vincule qualquer código de personalização no evento mobileinit antes de carregar o jQuery Mobile. Por exemplo, este código de exemplo usa o config.js para não utilizar transições animadas de páginas por padrão.

 
<script type="text/javascript" src="vendor/jquery/jquery-1.8.0.js"></script> <script type="text/javascript" src="app/config.js"></script> <script type="text/javascript" src="vendor/jqm/jquery.mobile-1.1.1.js"></script>
 
/* config.js: */ $(document).bind('mobileinit', function () { $.mobile.defaultPageTransition = 'none'; });

Dispositivos Testados:

  • Samsung Galaxy S* II smartphone (Google Android* 2.3.5, 480 x 800 pixels, hdpi)
  • Lava Xolo X900* smartphone (Android 2.3.7, 600 x 1024 pixels, hdpi)
  • Motorola Droid* Razr M smartphone (Android 4.0.4, 540 x 960 pixels, hdpi)
  • Asus Google Nexus* 7 tablet (Android 4.1.1; display: 7 inches, 1280 x 800 pixels, tvdpi)
  • Amazon Kindle Fire* 2 tablet (v.10.1.3 based on Android 4.0; display: 7 inches, 1024 x 600 pixels, mdpi)
  • Apple iPod Touch* 4th gen mobile device (Apple iOS* 4.3.1, 640 x 960 pixels, retina) !
  • Apple iPod Touch 4th gen mobile device (iOS 6.0, 640 x 960 pixels, retina)
  • Apple iPad* 2 tablet (iOS 5.1.1, 1024 x 768 pixels, non-retina)

! posicionamento fixo não suportado

Para obter informações mais completas sobre otimizações do compilador, consulte nosso aviso de otimização.