forked from drublic/css-modal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodal.js
139 lines (102 loc) · 3.13 KB
/
modal.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*!
* CSS Modal
* http://drublic.github.com/css-modal
*
* @author Hans Christian Reinl - @drublic
* @version 1.0.0
*/
(function (global) {
'use strict';
// Storage variable
var modal = {};
// Store for currently active element
modal.lastActive = undefined;
modal.activeElement = undefined;
// Polyfill addEventListener for IE8 (only very basic)
document._addEventListener = document.addEventListener || function (event, callback) {
document.attachEvent('on' + event, callback);
};
// Hide overlay when ESC is pressed
document._addEventListener('keyup', function (event) {
var hash = window.location.hash.replace('#', '');
// If hash is not set
if (hash === '' || hash === '!') {
return;
}
// If key ESC is pressed
if (event.keyCode === 27) {
window.location.hash = '!';
if (modal.lastActive) {
return false;
}
// Unfocus
modal.removeFocus();
}
}, false);
// Conveniance function to trigger event
modal._dispatchEvent = function (event, modal) {
var eventTigger;
if (!document.createEvent) {
return;
}
eventTigger = document.createEvent('Event');
eventTigger.initEvent(event, true, true);
eventTigger.customData = { 'modal': modal };
document.dispatchEvent(eventTigger);
};
// When showing overlay, prevent background from scrolling
window.onhashchange = function () {
var hash = window.location.hash.replace('#', '');
var modalChild;
// If hash is set
if (hash !== '' && hash !== '!') {
// Get first element in selected element
modalChild = document.getElementById(hash).children[0];
// When we deal with a modal and class `has-overlay` is not set on html yet
if (modalChild && modalChild.className.match(/modal-inner/) && !document.documentElement.className.match(/has-overlay/)) {
// Set an html class to prevent scrolling
document.documentElement.className += ' has-overlay';
// Mark modal as active
document.getElementById(hash).className += ' is-active';
modal.activeElement = document.getElementById(hash);
// Set the focus to the modal
modal.setFocus(hash);
// Fire an event
modal._dispatchEvent('cssmodal:show', modal.activeElement);
}
} else {
document.documentElement.className = document.documentElement.className.replace(' has-overlay', '');
// If activeElement is already defined, delete it
if (modal.activeElement) {
modal.activeElement.className = modal.activeElement.className.replace(' is-active', '');
// Fire an event
modal._dispatchEvent('cssmodal:hide', modal.activeElement);
// Reset active element
modal.activeElement = null;
// Unfocus
modal.removeFocus();
}
}
};
/*
* Accessibility
*/
// Focus modal
modal.setFocus = function (hash) {
if (modal.activeElement &&
typeof modal.activeElement.contains === 'function' &&
!modal.activeElement.contains(hash)) {
// Set element with last focus
modal.lastActive = document.activeElement;
// New focussing
modal.activeElement.focus();
}
};
// Unfocus
modal.removeFocus = function () {
if (modal.lastActive) {
modal.lastActive.focus();
}
};
global.CSSModal = modal;
}(window));