Desenvolvimento - Javascript

Estrutura de abas com botão fechar em HTML, CSS e jQuery

Veja neste artigo como desenvolver uma estrutura de abas com botão para fechar as guias, utilizando HTML, CSS e jQuery.

por Joel Rodrigues



O objetivo deste artigo é demonstrar como desenvolver uma estrutura de abas com botão para fechar, utilizando HTML, CSS e Javascript, mais especificamente, a biblioteca jQuery. Utilizaremos aqui apenas recursos básicos das web Standards, sem a necessidade de qualquer ferramenta gráfica avançada.

Em várias aplicações, vemos interfaces divididas em abas que possuem um botão para fechar cada guia. Apesar deste tipo de estrutura ser menos comum em aplicações web, veremos que é possível desenvolver uma solução deste tipo de forma rápida e de fácil compreensão. Para isso, utilizaremos apenas HTML, CSS e Javascript (jQuery).

Observação: o código aqui exposto foi testado nas versões mais atuais do Internet Explorer, Google Chrome e Mozila Firefox, e funcionou normalmente. Porém, no Internet Explorer não há suporte para a propriedade “border-radius” das CSS3 que foram utilizadas neste artigo, mesmo assim, a diferença será apenas em uma parte do layout do cabeçalho das abas.

Desenvolveremos nossa solução em três arquivos: index.html, scriptAbas.js e estiloAbas.css, que contém, respectivamente, a estrutura HTML, o script jQuery e a folha de estilos utilizada.

Vejamos então o arquivo index.html na Listagem 1.

Listagem 1: Arquivo index.html

<html>
<head>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
    <script type="text/javascript" src="scriptAbas.js"></script>
    <link rel="stylesheet" type="text/css" href="estiloAbas.css" />    
</head>
<body>

<div class="TabControl">
    <div id="header">
        <ul class="abas">
            <li>
                <div class="aba">
                    <span>Tab 1</span>		
                </div>
            </li>
            <li>
                <div class="aba">
                    <span>Tab 2</span>
                </div>
            </li>
            <li>
                <div class="aba">
                    <span>Tab 3</span>
                </div>
            </li>
            <li>
                <div class="aba">
                    <span>Tab 4</span>
                </div>
            </li>
        </ul>
    </div>
    <div id="content">
        <div class="conteudo">
            Conteúdo da aba 1
        </div>
        <div class="conteudo">
            Conteúdo da aba 2
        </div>
        <div class="conteudo">
            Conteúdo da aba 3
        </div>
        <div class="conteudo">
            Conteúdo da aba 4
        </div>
    </div>
</div>
</body>
</html>

No início, é feita referência aos arquivos js e css que darão à página a funcionalidade e aparência desejada.

Temos três divs formando a estrutura das abas: a div TabControl é utilizada como container geral, enquanto as divs Header e Content são, respectivamente, os cabeçalhos e as páginas.

Após aplicar a folha de estilos que pode ser vista na Listagem 2, a página tomará uma forma mais adequada ao fim que se destina, porém, ainda sem funcionalidade de mudança ou fechamento de abas.

Listagem 2: Arquivo estiloAbas.css

body{font-family:Calibri, Tahoma, Arial}

 .TabControl{
    width:100%;
    overflow:hidden;
    height:400px}

 .TabControl #header{
    width:100%;
    overflow:hidden;
    cursor:hand}

 .TabControl #content{
    width:100%;
    border: solid 1px #27408B;
    overflow:hidden;
    height:100%; }
 
 .TabControl .abas{display:inline;}
 
 .TabControl .abas li{float:left}
 
 .abas{
    list-style:none;
 }
 .aba{
    width:100px;
    height:30px;
    border:solid 1px;
    border-radius:5px 5px 0 0;
    text-align:center;
    padding-top:5px;
    background:#3A5FCD;
    border-bottom-color:#27408B}
 
 .ativa{
    width:100px;
    height:30px;
    border:solid 1px #27408B;
    border-radius:5px 5px 0 0;
    text-align:center;
    padding-top:5px;
}

.ativa span, .selecionada span{color:#fff}

.TabControl #content{background:#27408B}

.TabControl .conteudo{
    width:100%;
    background:#27408B;
    display:none;
    height:100%;
    color:#fff}

.selecionada{
    width:100px;
    height:30px;
    border:solid 1px #27408B;
    border-radius:5px 5px 0 0;
    text-align:center;
    padding-top:5px;
    background:#27408B}}

A aparência da página até o momento é exibida na Figura 1.

Aparência da página após aplicação da folha de estilos

Figura 1: Aparência da página após aplicação da folha de estilos

Tanto o código HTML quanto o CSS são bem simples e, creio eu, dispensam maiores explicações. Enfatizaremos, aqui, o script que tornará dinâmica a estrutura que criamos até agora. Vamos então a ele.

Em scripts jQuery externos, o conteúdo fica no corpo de uma função que é carregada junto com a página, como é exibido na Listagem 3. Todas os métodos que veremos a seguir devem ficar dentro desta função.

Listagem 3: Estrutura geral do arquivo scriptAbas.js

$(function(){
	//Corpo da função
	//Todo conteúdo deve ficar aqui
});

Nas listagens que seguem, veremos vários trechos do código Javascript comentado, explicando qual sua função.

Listagem 4: Selecionando a primeira aba por padrão

$("#content div:nth-child(1)").show();
$(".abas li:first div").addClass("selecionada");   

Nas duas linhas da Listagem 2, utilizamos o seletor CSS nth-child(N) para marcar a primeira aba com a classe “selecionada”, o que lhe dá destaque junto as demais e exibimos o conteúdo da primeira página.

Listagem 5: Destacando as abas ao passar o mouse por cima

$(".aba").hover(
    function(){$(this).addClass("ativa")},
    function(){$(this).removeClass("ativa")}
);

Na Listagem 5, utilizamos a função hover que gerencia a passagem do mouse sobre o controle. No corpo desta função, escrevemos outras duas funções que são executadas quando o cursor é posto sobre o elemento e retirado, respectivamente. No caso, quando o usuário passar o cursor sobre o cabeçalho da guia, este receberá a classe “ativa” e terá sua aparência alterada, quando o cursor for retirado do cabeçalho, o mesmo voltará a sua aparência inicial.

Listagem 6: Adicionando os botões de fechar as guias

$(".aba").append("<img src='close.png'>");

Com apenas uma linha de código, inserimos uma imagem (no meu caso, utilizei um “X” vermelho de dimensões 16x16) a todas a abas. A aparência da página agora deve ser a exibida na Figura 2.

Aparência da página após aplicação do script

Figura 2: Aparência da página após aplicação do script

Porém, até o momento, não podemos mudar de guia ou fechar uma das páginas. Essas funcionalidades serão adicionadas nas próximas duas listagens. Sim, precisaremos de apenas mais duas funções para “dar vida” ao conteúdo.

Listagem 7: Código para permitir a mudança de página

$(".aba").click(function(){
    $(".aba").removeClass("selecionada");
    $(this).addClass("selecionada");
    var indice = $(this).parent().index();
    indice++;
    $("#content div").hide();
    $("#content div:nth-child("+indice+")").show();
});

A Listagem 7 pode ser explicada linha a linha:

  • 2. Remove a classe “selecionada” de todas as abas;
  • 3. Marca somente a aba clicada como selecionada;
  • 4. Recupera o índice da aba selecionada (começando do zero);
  • 5. Incrementa o índice para usar posteriormente;
  • 6. Esconde todas as páginas (conteúdos);
  • 7. Exibe apenas a página selecionada pelo índice (começando do 1);

Vendo de forma detalhada, concluímos que o código em si não é complicado. Abrindo a página no browser, já é possível alternar entre as guias. A próxima listagem implementa o fechamento das páginas ao clicar sobre o botão (a imagem adicionada anteriormente).

Listagem 8: Implementação do fechamento das guias

$(".aba > img").click(function(){
    var aba = $(this).parent().parent();    		
    var indice = aba.index() + 1;
    aba.remove();
    $("#content div:nth-child("+indice.toString()+")").remove();
    $(".aba").removeClass("selecionada");
    $("#content div").hide();
    if(indice>1){
        var id = indice - 1;                
        $("#content div:nth-child("+id.toString()+")").show();                
        $(".abas  li:nth-child("+id+") .aba").addClass("selecionada");
    }else{                
        $("#content div:nth-child("+indice.toString()+")").show();                
        $(".abas  li:nth-child("+indice+") .aba").addClass("selecionada");
    }
});

Novamente vejamos a explicação de cada linha:

  • 2. Recupera a aba selecionada (a tag <li>);
  • 3. Recupera o índice da aba selecionada e incrementa para usar posteriormente;
  • 4. Remove o cabeçalho da aba clicada;
  • 5. Remove o conteúdo da página selecionada pelo índice;
  • 6. Remove a classe “selecionada” de todos os cabeçalhos, deixando todos iguais;
  • 7. Esconde o conteúdo de todas as páginas;
  • 8. Se a página fechada não for a primeira, sua antecessora será selecionada;
  • 9. Declara uma variável que vale “índice-1” para selecionar a aba anterior;
  • 10. Exibe o conteúdo da página anterior a fechada;
  • 11. Marca o cabeçalho da aba anterior a fechada como selecionado;
  • 12. Se a página fechada for a primeira, sua sucessora será selecionada;
  • 13. Exibe o conteúdo da página posterior a fechada;
  • 14. Marca o cabeçalho da aba posterior a fechada como selecionado;

Novamente pode-se abrir o arquivo no browser e testar. Clicando sobre o botão de fechar, a guia é removida.

Como vimos ao longo deste artigo, o jQuery, juntamente com os seletores e atributos das CSS nos permitem desenvolver, de forma rápida, conteúdos que antes eram muito complicados de serem feitos. É importante observar também que não utilizamos nenhum recurso muito avançado de nenhuma das web Standards.

Concluo assim mais este artigo, o qual espero que tenha sido útil.

Um abraço a todos e até a próxima publicação.

Joel Rodrigues

Joel Rodrigues - Técnico em Informática - IFRN Cursando Bacharelado em Ciências e Tecnologia - UFRN Programador .NET/C# e Delphi há quase 3 anos, já tendo trabalhado com Webservices, WPF, Windows Phone 7 e ASP.NET, possui ainda conhecimentos em HTML, CSS e Javascript (JQuery).