jQuery – Criando uma classe para Modal

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.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *