So you want to build your own modal box using jQuery instead of using an existing plugin? ...OK, let's play (as it was already pointed out, using popups is not a user-friendly solution):
Your check list :
- the trigger
- the shadow layer
- the modal box size and position
- add content to modal and display it along the shadow
1) The trigger is a simple html link to open the content inside the modal
<a href="http://jsfiddle.net" class="myModal" data-width="400" data-height="300">open url</a>
... we will pass the size of the modal via data-width
and data-height
(HTML5) attributtes.
2) The shadow
layer is the html structure that we will append to the body after the trigger. We can set the structure in a js variable
var shadow = "<div class='shadow'></div>";
3) As we mentioned, the size of the modal is set through some data-*
attributes in the link. We would need to do some math
var modalWidth = $(this).data("width");
var modalHeight = $(this).data("height");
var modalX = (($(window).innerWidth()) - modalWidth) / 2; // left position
var modalY = (($(window).innerHeight()) - modalHeight) / 2; // top position
NOTE : $(this)
is our trigger selector .myModal
that we'll get inside an .on("click")
method later on. BTW, the .on()
method requires jQuery v1.7+
4) Now we need to create the modal's html structure and pass the content href
. We'll create a function
function modal(url) {
return '<div id="modal"><a id="closeModal" title="close" href="javascript:;"><img src="http://findicons.com/files/icons/2212/carpelinx/64/fileclose.png" alt="close" /></a><iframe src="' + url + '"></iframe></div>';
}
... as you can see, our structure contains a close button to remove the modal and the shadow layer. The function also gets a parameter when is called (url
) which allows to set the src
attribute of the iframe
tag.
NOTE : we have to use the iframe
tag to open external urls, however we should always consider the same origin policy and other security restrictions when using iframes.
So now, we need to put together all the events after we click on our .myModal
trigger, which are appending both the shadow and the modal box to the body and to remove them when we click on the close button so
$(".myModal").on("click", function(e) {
e.preventDefault();
// get size and position
modalWidth = $(this).data("width");
modalHeight = $(this).data("height");
modalX = (($(window).innerWidth()) - modalWidth) / 2;
modalY = (($(window).innerHeight()) - modalHeight) / 2;
// append shadow layer
$(shadow).prependTo("body").css({
"opacity": 0.7
});
// append modal (call modal() and pass url)
$(modal(this.href)).appendTo("body").css({
"top": modalY,
"left": modalX,
"width": modalWidth,
"height": modalHeight
});
// close and remove
$("#closeModal").on("click", function() {
$("#modal, .shadow").remove();
});
}); // on
STYLE : of course we will need some basic CSS style to make our modal elements work properly:
.shadow {width: 100%; height: 100%; position: fixed; background-color: #444; top: 0; left:0; z-index: 400}
#modal {z-index: 500; position: absolute; background: #fff; top: 50px;}
#modal iframe {width: 100%; height: 100%}
#closeModal {position: absolute; top: -15px; right: -15px; font-size: 0.8em; }
#closeModal img {width: 30px; height: 30px;}
* SEE DEMO *
BONUS : you could also bind a keyup
event to close the modal using the escape
key
$(document).keyup(function(event) {
if (event.keyCode === 27) {
$("#modal, .shadow").remove();
}
}); //keyup
LAST NOTE : the code is subject to many improvements and optimization but is a basic layout of what many lightboxes do. My last recommendation : use fancybox for more advanced functionality ... sometimes it doesn't worth the effort to re-invent the wheel ;)