Estava estudando algumas coisas de jQuery em um tempo livre no trampo e comecei a desenvolver uma classe de modal para jQuery. Sei que já existem várias, lightbox, facebox, e outras, mas fiz para estudar mesmo.
Nunca havia feito um modal do zero – sei que usei uma biblioteca, então não foi do zero mesmo mesmo – mas achei a experiência bem satisfatória e menos traumática do que eu pensava.
Vou explicar primeiro o que a classe se propõem a fazer
Requisitos
- Biblioteca jQuery
Funcionalidades
- Pode criar diversos modais (iniciando a classe mais de uma vez)
- Carrega imagens (jpg,jpeg,gif,png) e ajusta o modal no tamanho da imagem
- Carrega elementos de objetos html da página no modal
- Carrega html externo (ajax) no modal
- Gera as funções para todos os links utilizando o atributo "rel"
Bugs conhecidos
- Não redimensiona a altura do modal para um tamanho menor do atual (no IE)
Devem existir mais, pelo que lembro até tinha relatado mais alguns, mas esqueci de anotar e aí… 😛
Testei o modal em Firefox, Internet Explorer 8, Internet Explorer 7 (emulado), Internet Explorer 6 (emulado). Tenho algumas idéias que gostaria de implementar mas nem testei ainda, segue a lista para quem quiser se arriscar:
- Navegação entre os contents ou imagens do modal
- Melhorar o sistema de resize
- Melhorar o layout
- Implementar exibição de vídeos do Youtube diretamente do link
O código
O código estava bem simples até eu começar a fazer alguns ajustes para o IE.. mas enfim, como é típico do jQuery, acredito que o código está bem "legível", segue a classe:
/* ### Modal Class ### * Author: Guilherme Serrano * Using jQuery * * ### How to ### * var name = new Modal(name, mask) * * # Arguments # * name = id único * mask (true/false) = using mask * * All links with rel="name" will open modal box * */ function Modal(modalName,mask){ //Vars maxHeight = 450; maxWidth = 650; thisClass = this; //Initialize modal this.initialize = function(){ //Create elements & vars if($("#"+modalName).size() < 1){ $("body").append("<div id="" + modalName + ""></div>") } divModal = $("#"+modalName); divModal.addClass("modal"); var content = divModal.html(); divModal.html(""); divModal.prepend("<div class="modal_top"><a href="#" title="Fechar esta janela" id="" + modalName +"_close">Fechar</a></div><div class="modal_content"></div>"); $("#"+modalName +" .modal_content").html(content); //Mask if(mask){ if ($("#divMask").size() < 1) { divMask = "<div id="divMask" style="height:" + $(document).height() + "px;"></div>"; $(divMask).appendTo("body"); } } //Close button $("#"+modalName +"_close").click(function(){ thisClass.close(); }); divContent = $("#"+modalName +" .modal_content"); //Centralize on resize window $(window).bind("resize", function() { thisClass.centralize(); }); //Open buttons $("a[rel=""+modalName+""]").click(function(){ href = $(this).attr("href") if(href == null || href == "" || href == "undefined" || href == "#"){ thisClass.open(); }else{ thisClass.open(href) } return false; }) } //Open this.open = function(content){ thisClass.setContent(content); if (mask) { thisClass.showElement("#divMask"); } thisClass.showElement("#"+modalName); thisClass.setMeasures(); } //Close this.close = function(){ if(mask){ thisClass.hideElement("#divMask"); } thisClass.hideElement("#"+modalName); } //Load content this.setContent = function(content){ if(content != undefined && content != null && content != ""){ if(content.match(/.gif/) || content.match(/.jpg/) || content.match(/.jpeg/) || content.match(/.png/)){ divContent.html("<img src=""+content+"" />"); }else if(content.match(/http:///) || content.match(/https:///) || content.match(/file:///)){ divContent.load(content, null, thisClass.setMeasures); }else{ divContent.html($(content).html()); } } } //Show this.showElement = function(e){ $(e).show(); } //Hide this.hideElement = function(e){ $(e).hide(); } //Centralize this.centralize = function(){ var posTop = (($(window).height()/2) - (divModal.height()/2)) var posLeft = (($(window).width()/2) - (divModal.width()/2)) divModal.css({ "top" : posTop + "px", "left" : posLeft + "px" }); } this.setMeasures = function(){ thisClass.setWidth(); thisClass.setHeight(); thisClass.centralize(); } // Set height this.setHeight = function(){ h = divContent.height() if(h > maxHeight){ divContent.css({ "height": maxHeight+"px" }) divModal.css({ "height": (maxHeight+50)+"px" }) }else{ divModal.css({ "height": "auto" }) } } this.setWidth = function(){ w = divContent.width() if(w > maxWidth){ divModal.css({ "width": (maxWidth+20)+"px" }) }else{ divModal.css({ "width": "auto" }) if(divContent.width() > maxWidth){ //alert("Deixou auto, ficou maior, reduziu!") divModal.css({ "width": (maxWidth+20)+"px" }) } } } }
E o CSS
.modal { position: absolute; z-index: 99999; display: none; background: #fff; border: 2px solid #777; } .modal_content{ border: 1px solid #333; margin: 5px; padding: 5px; overflow: auto; _height: expression(this.height > 450 ? 450: true); max-height: 450px; } .modal_content div{ border: 2px solid blue; height: auto; } #divMask { background-color:#000; width: 100%; left:0px; margin:0px; padding:0px; position:absolute; top:0px; z-index:1000; opacity:0.8; filter:alpha(opacity=80); display: none; }
Como fiz a classe para estudos não utilizei nenhuma imagem e estou publicando sem formatar bonitinho o header do modal (botão para fechar).
Como utilizar
O uso ficou bastante simples, é só iniciar o modal e criar os links que devem abrir. Segue um exemplo da criação de um modal chamado "modal":
$(document).ready(function(){ var modal = new Modal("modal",true) modal.initialize(); });
O código acima acessa a função "initialize" da classe, o primeiro parâmetro (modal) é o nome do seu modal, que pode ser qualquer um. O segundo parâmetro (true) é um boolean, e define se será utilizado a mask para escurecer o fundo do site e destacar apenas o modal ou não.
Os links devem ter o atributo rel igual ao nome do modal que você iniciou (no exemplo de cima, rel="modal") e o atributo href indica qual o conteúdo será exibido no modal (pode ser link externo, link para imagem ou o id de algum elemnto da página atual.
<a href="#" rel="modal">Open modal</a><br /> <a href="http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif" rel="modal">Open external image</a><br /> <a href="#content" rel="modal">Open div#content content</a><br /> <a href="https://andafter.org/" rel="modal">Open external page</a><br />
Conclusão
Gostei da brincadeira, o tempo de desenvolvimento não fui muito longo, comecei no trabalho e terminei em casa, depois fiz alguns ajustes. A biblioteca jQuery é realmente mágica, o código estava bastante curto, pouquíssimas linhas e um modal funcionando.
O código aumentou na medida que comecei a adiconar funcionalidade (identificar o tipo de conteúdo, criar automaticamente as actions para os links com o atributo rel, redimensionar e reposicionar o modal quando a janela é aberta, etc…)
No IE ainda ficou a pendência de fazer o modal diminuir a altura.