-
Notifications
You must be signed in to change notification settings - Fork 20
/
Dialog.js
111 lines (80 loc) · 2.33 KB
/
Dialog.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
function Dialog(dialogEl, overlayEl) {
this.dialogEl = dialogEl;
this.overlayEl = overlayEl;
this.focusedElBeforeOpen;
var focusableEls = this.dialogEl.querySelectorAll('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex="0"]');
this.focusableEls = Array.prototype.slice.call(focusableEls);
this.firstFocusableEl = this.focusableEls[0];
this.lastFocusableEl = this.focusableEls[ this.focusableEls.length - 1 ];
this.close(); // Reset
}
Dialog.prototype.open = function() {
var Dialog = this;
this.dialogEl.removeAttribute('aria-hidden');
this.overlayEl.removeAttribute('aria-hidden');
this.focusedElBeforeOpen = document.activeElement;
this.dialogEl.addEventListener('keydown', function(e) {
Dialog._handleKeyDown(e);
});
this.overlayEl.addEventListener('click', function() {
Dialog.close();
});
this.firstFocusableEl.focus();
};
Dialog.prototype.close = function() {
this.dialogEl.setAttribute('aria-hidden', true);
this.overlayEl.setAttribute('aria-hidden', true);
if ( this.focusedElBeforeOpen ) {
this.focusedElBeforeOpen.focus();
}
};
Dialog.prototype._handleKeyDown = function(e) {
var Dialog = this;
var KEY_TAB = 9;
var KEY_ESC = 27;
function handleBackwardTab() {
if ( document.activeElement === Dialog.firstFocusableEl ) {
e.preventDefault();
Dialog.lastFocusableEl.focus();
}
}
function handleForwardTab() {
if ( document.activeElement === Dialog.lastFocusableEl ) {
e.preventDefault();
Dialog.firstFocusableEl.focus();
}
}
switch(e.keyCode) {
case KEY_TAB:
if ( Dialog.focusableEls.length === 1 ) {
e.preventDefault();
break;
}
if ( e.shiftKey ) {
handleBackwardTab();
} else {
handleForwardTab();
}
break;
case KEY_ESC:
Dialog.close();
break;
default:
break;
}
};
Dialog.prototype.addEventListeners = function(openDialogSel, closeDialogSel) {
var Dialog = this;
var openDialogEls = document.querySelectorAll(openDialogSel);
for ( var i = 0; i < openDialogEls.length; i++ ) {
openDialogEls[i].addEventListener('click', function() {
Dialog.open();
});
}
var closeDialogEls = document.querySelectorAll(closeDialogSel);
for ( var i = 0; i < closeDialogEls.length; i++ ) {
closeDialogEls[i].addEventListener('click', function() {
Dialog.close();
});
}
};