Skip to content

Instantly share code, notes, and snippets.

@rafaelcanovas
Last active April 20, 2016 19:15
Show Gist options
  • Save rafaelcanovas/cc28e830bd0187b95745fa464cd11802 to your computer and use it in GitHub Desktop.
Save rafaelcanovas/cc28e830bd0187b95745fa464cd11802 to your computer and use it in GitHub Desktop.
Simple modal windows
(function ($) {
'use strict';
// Compat
MutationObserver = window.MutationObserver ||
window.WebKitMutationObserver ||
window.MozMutationObserver;
var body = $(document.body),
modalOverlay = $('<div>', {'id': 'modal-overlay'}).appendTo(body),
modalTriggers = $('a[data-modal-id]');
var setupModal = function (e, modalID) {
if (e) e.preventDefault();
var modal = $('#' + (e ? $(this).attr('data-modal-id') : modalID)),
modalObserver = MutationObserver ? new MutationObserver(autoPosModal) : undefined;
// Check if the modal triggered really exists before doing anything more
if (!modal.length || !modal.hasClass('modal'))
return;
function showModal() {
body.css('overflow', 'hidden');
body.on('keyup.modals', function (e) {
if (e.which == 27)
hideModal();
});
body.one('click.modals', '.modal-close-button', hideModal);
modalOverlay.addClass('active');
modalOverlay.one('click', hideModal);
modal.addClass('active');
if (modalObserver)
modalObserver.observe(modal.get(0), {
'childList': true,
'subtree': true
});
else
modal.on('DOMNodeInserted.modals', autoPosModal);
$(window).on('resize.modals', autoPosModal);
}
function hideModal(e) {
if (e) e.preventDefault();
body.css('overflow', 'auto');
body.off('.modals');
modalOverlay.removeClass('active');
modalOverlay.off();
modal.removeClass('active');
modal.off('.modals');
if (modalObserver)
modalObserver.disconnect();
$(window).off('resize.modals');
// Remove the modal hash if any
if (location.hash)
location.hash = '';
}
function autoPosModal() {
var screenH = $(window).height(),
screenW = $(window).width(),
modalH = modal.outerHeight(true),
modalW = modal.outerWidth(true),
topGap = Math.floor(screenH/2 - modalH/2),
leftGap = Math.floor(screenW/2 - modalW/2);
modal.css('top', topGap + 'px')
.css('left', leftGap + 'px');
}
showModal();
autoPosModal();
modal.on('hide', hideModal);
};
// When a trigger is clicked, show the correpondent modal
modalTriggers.on('click', setupModal);
// On page load, if a hash corresponding to a modal is specified, show it
if (location.hash)
setupModal(null, location.hash.substring(1));
// Tries to open a modal when changes in location.hash is detected
$(window).on('hashchange', function (e) {
var hash = location.hash.substring(1);
if (hash)
setupModal(null, hash);
});
// Public methods
window.modals = window.modals || {};
window.modals.showModal = function (modalID) {
setupModal(null, modalID);
};
window.modals.hideModal = function (modalID) {
$('#' + modalID).trigger('hide');
};
})(jQuery);
#modal-overlay {
background: transparentize(black, 0.5);
height: 100%;
left: 0;
opacity: 0;
position: fixed;
top: 0;
visibility: hidden;
width: 100%;
z-index: 1000;
&.active {
opacity: 1;
visibility: visible;
}
}
@keyframes modalFadeInAnimation {
from {
opacity: 0;
transform: scale(1.1);
}
to {
opacity: 1;
transform: scale(1);
}
}
.modal {
background: white;
box-shadow: 0 0 0 1px color(lighter-gray);
border-radius: 3px;
opacity: 0;
padding: 20px;
position: fixed;
visibility: hidden;
width: 750px;
z-index: 1001;
&.active {
animation: modalFadeInAnimation 500ms forwards;
visibility: visible;
}
}
.modal-close-button-container {
text-align: right;
a.modal-close-button {
position: relative;
right: 0;
top: 0;
}
}
.modal-close-button {
background: url('../img/modal-close-button.png') no-repeat center center;
display: inline-block;
height: 16px;
width: 16px;
position: absolute;
top: 20px;
right: 20px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment