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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
'use strict';
/**
* @name Novicell overlay
* @desc Simple script that opens an overlay / modal with some content form either a selector or an URL
* @author Danni Larsen (DLA), Michael Sølvsteen (MSL), Signe Helbo Poulsen (SHP), Emil Skytte Ankersen (EAN)
* @example novicell.overlay.create({ 'selector': SELECTOR, 'url': URL, 'class':'CLASSNAME', 'onCreate': FUNCTIONNAME, 'onLoaded': FUNCTIONNAME, 'onDestroy': FUNCTIONNAME });
* @requires none
*/
var novicell = novicell || {};
novicell.overlay = novicell.overlay || new function () {
var self = this;
var options = {};
var overlayElem;
var overlayContainer;
var overlayContent;
var backdrop;
var content;
var onCreate;
var onLoaded;
var onDestroy;
var isVideo = false;
this.create = function (opts) {
var self = this;
// Set global options
options = opts;
// Call onCreate callback
if (typeof options.onCreate === 'function') {
options.onCreate();
}
// Remove existing overlays
self.destroy();
// Check if content comes from a DOM selector
if (options.hasOwnProperty('selector') && options.selector !== null) {
var element = document.querySelector(options.selector);
if (element) {
content = element.innerHTML;
constructOverlay();
} else {
console.warn('novicell.overlay: element does not exist. Please provide a valid selector for use in document.querySelector.');
return;
}
}
// Check if content comes from a HTML element
else if (options.hasOwnProperty('element') && options.element !== null) {
var element = options.element;
if (element) {
content = element.innerHTML;
constructOverlay();
} else {
console.warn('novicell.overlay: element does not exist. Please provide a valid DOM element.');
return;
}
}
// Or if content comes from an ID
else if (options.hasOwnProperty('videoId')) {
if (options.videoId !== null) {
var src = '';
isVideo = true;
if(options.type == 'vimeo') {
src = 'https://player.vimeo.com/video/' + options.videoId + '?autoplay=' + options.autoplay;
}
else if(options.type == 'youtube') {
src = 'https://www.youtube.com/embed/' + options.videoId + '?autoplay=' + options.autoplay + '&rel=0';
}
else {
return;
}
var iframe = document.createElement('iframe');
iframe.setAttribute('src', src);
iframe.setAttribute('frameborder', 0);
iframe.setAttribute('allowfullscreen', '');
iframe.setAttribute('width', '100%');
iframe.setAttribute('height', '100%');
content = iframe.outerHTML;
constructOverlay();
} else {
console.warn('novicell.overlay: video-id is empty. Please provide a video-id for use in video embed code (we support only Vimeo and YouTube).');
return;
}
}
// If nothing is working, send error to los consolé
else {
console.error('novicell.overlay: no content to display! Please set a selector or a url to load.')
return;
}
};
this.destroy = function () {
if(document.querySelector('#js-novi-overlay')) {
// Remove elements
overlayElem.parentElement.removeChild(overlayElem);
backdrop.parentElement.removeChild(backdrop);
// Stop listening for close overlay events
document.removeEventListener('keyup', self.destroy);
// Remove class on body
document.documentElement.classList.remove('no-scroll', 'novi-overlay--open');
// Reset video variable
isVideo = false;
// Call onDestroy callback
if (typeof options.onDestroy === 'function') {
options.onDestroy();
}
}
};
function constructOverlay() {
// Create backdrop
setupBackdrop();
// Create the overlay
setupOverlay();
// Create content for overlay
setupOverlayContainer();
// Create close button
setupCloseButton();
// Add class to body-element
document.documentElement.classList.add('no-scroll');
// Call onLoaded callback
if (typeof options.onLoaded === 'function') {
options.onLoaded();
}
};
function setupBackdrop() {
// Create the backdrop
backdrop = document.createElement('div');
backdrop.classList.add('novi-backdrop');
backdrop.id = 'js-novi-backdrop';
backdrop.addEventListener('click', function(e){
if(e.target.classList.contains('novi-overlay') || e.target.classList.contains('novi-overlay__container')) {
self.destroy();
}
});
// Add backdrop to overlay element
document.querySelector('body').appendChild(backdrop);
};
/*
* Helper functions for HTML elements
*/
function setupOverlay() {
// Create the overlay
overlayElem = document.createElement('div');
overlayElem.classList.add('novi-overlay');
overlayElem.id = 'js-novi-overlay';
// Set class for the overlay, if set in options
if (options.hasOwnProperty('class')) {
overlayElem.classList.add(options.class);
}
// Add overlay to overlay element
// document.querySelector('body').appendChild(overlayElem);
backdrop.appendChild(overlayElem);
};
function setupOverlayContainer() {
// Create content for overlay
overlayContainer = document.createElement('div');
overlayContainer.classList.add('novi-overlay__container');
// Create scroll element
overlayContent = document.createElement('div');
overlayContent.classList.add('novi-overlay__content');
if(isVideo) {
overlayContent.classList.add('novi-overlay__content--video')
}
// Set content
overlayContent.innerHTML = content;
overlayContainer.appendChild(overlayContent);
// Add overlayContainer to overlay element
overlayElem.appendChild(overlayContainer);
};
function setupCloseButton() {
// Create the button
var btnClose = document.createElement('button');
btnClose.classList.add('novi-overlay-close', 'button--close');
btnClose.type = 'button';
btnClose.id = 'js-novi-overlay-close';
// Add eventlistener for button click
btnClose.addEventListener('click', self.destroy);
// Add eventlistener for esc key
document.addEventListener('keydown', function (e) {
if (e.keyCode === 27) {
self.destroy();
}
});
// Add close button to overlay element
overlayContent.appendChild(btnClose);
};
/*
* Helper functions for getting content
*/
function get(url) {
// Return a new promise.
return new Promise(function (resolve, reject) {
// Do the usual XHR stuff
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function () {
if (req.status >= 200 && req.status < 400) {
// Success!!
resolve(req.response);
} else {
// Error!!
reject(Error(req.statusText));
}
};
// Handle network errors
req.onerror = function () {
reject(Error("Network Error"));
};
// Make the request
req.send();
});
};
}();
|