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
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.