Skip to content

Commit bd0908a

Browse files
committed
Add activeElement restore demo.
1 parent 69c8c9a commit bd0908a

File tree

3 files changed

+168
-0
lines changed

3 files changed

+168
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ with.
1010

1111
## My JavaScript Demos - I Love JavaScript!
1212

13+
* [Restoring ActiveElement Focus After A User-Interaction In JavaScript](https://bennadel.github.io/JavaScript-Demos/demos/restoring-active-element/)
1314
* [Trapping Focus Within An Element Using Tab-Key Navigation In JavaScript](https://bennadel.github.io/JavaScript-Demos/demos/focus-capture/)
1415
* [Applying Multiple Animation Keyframes To A Loading Indicator In CSS](https://bennadel.github.io/JavaScript-Demos/demos/multiple-animations-css/)
1516
* [Capturing Keyboard Event Modifiers Across Operating Systems In JavaScript](https://bennadel.github.io/JavaScript-Demos/demos/keydown-os-modifier/)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
2+
body {
3+
font-family: sans-serif ;
4+
font-size: 18px ;
5+
}
6+
7+
button {
8+
font-size: 100% ;
9+
}
10+
11+
button:focus {
12+
outline: 3px solid #ff3366 ;
13+
}
14+
15+
.modal {
16+
align-items: center ;
17+
background-color: rgba( 0, 0, 0, 0.8 ) ;
18+
bottom: 0px ;
19+
display: none ;
20+
justify-content: center ;
21+
left: 0px ;
22+
overscroll-behavior: contain ;
23+
position: fixed ;
24+
right: 0px ;
25+
top: 0px ;
26+
}
27+
28+
.modal--open {
29+
display: flex ;
30+
}
31+
32+
.modal__panel {
33+
background-color: #ffffff ;
34+
border-radius: 5px 5px 5px 5px ;
35+
padding: 30px 30px 30px 30px ;
36+
}
37+
38+
.modal__panel:focus,
39+
.modal__panel:focus-within {
40+
outline: 4px dotted #ffffff ;
41+
}
42+
43+
.modal__panel > *:first-child {
44+
margin-top: 0px ;
45+
}
46+
.modal__panel > *:last-child {
47+
margin-bottom: 0px ;
48+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>
6+
Restoring ActiveElement Focus After A User-Interaction In JavaScript
7+
</title>
8+
<link rel="stylesheet" type="text/css" href="./demo.css" />
9+
</head>
10+
<body>
11+
12+
<h1>
13+
Restoring ActiveElement Focus After A User-Interaction In JavaScript
14+
</h1>
15+
16+
<p class="trigger">
17+
<button>Open modal (1)</button> , <button>Open modal (2)</button> ,
18+
<button>Open modal (3)</button> , <button>Open modal (4)</button>
19+
</p>
20+
<p class="trigger">
21+
<button>Open modal (5)</button> , <button>Open modal (6)</button> ,
22+
<button>Open modal (7)</button> , <button>Open modal (8)</button>
23+
</p>
24+
25+
<!--
26+
Our modal window is going to be hidden by default. When triggered, it will take
27+
over the focus; and, when closed, focus will be returned to the element that
28+
originally triggered it.
29+
-->
30+
<div class="modal">
31+
<div role="dialog" aria-labelledby="modal-title" class="modal__panel">
32+
<h2 id="modal-title">
33+
Hello, Modal
34+
</h2>
35+
<p>
36+
<button>Close</button>
37+
</p>
38+
</div>
39+
</div>
40+
41+
<script type="text/javascript" src="../../vendor/jquery/3.6.0/jquery-3.6.0.min.js"></script>
42+
<script type="text/javascript">
43+
44+
var trigger = $( ".trigger" )
45+
.on( "click", "button", openModal )
46+
;
47+
var modal = $( ".modal" )
48+
.on( "click", handleModalClick )
49+
;
50+
var panel = modal
51+
.find( ".modal__panel" )
52+
// We're applying tabindex to the modal panel so that we can programmatically
53+
// focus the panel after we open the modal window.
54+
.attr( "tabindex", "-1" )
55+
.on( "click", "button", closeModal )
56+
;
57+
58+
// I keep track of element that triggered the modal window.
59+
var previousElement = null;
60+
61+
// --------------------------------------------------------------------------- //
62+
// --------------------------------------------------------------------------- //
63+
64+
// I open the modal window and draw focus into the modal container.
65+
function openModal() {
66+
67+
// We're about to open the modal window and draw focus into the modal panel.
68+
// But, before we do that, we want to track which element triggered the modal
69+
// so that we can restore focus to that element when the modal is closed.
70+
previousElement = ( document.activeElement || document.body );
71+
72+
modal.addClass( "modal--open" );
73+
panel.focus();
74+
75+
console.group( "Taking focus away from trigger" );
76+
console.log( previousElement );
77+
console.groupEnd();
78+
79+
}
80+
81+
82+
// I close the modal window and return focus to the previous element.
83+
function closeModal() {
84+
85+
modal.removeClass( "modal--open" );
86+
87+
// If we have a reference to the original trigger, let's restore focus to
88+
// that the trigger so the user can pick-up where they left off.
89+
if ( previousElement ) {
90+
91+
console.group( "Restoring focus to previously-active element" );
92+
console.log( previousElement );
93+
console.groupEnd();
94+
95+
previousElement.focus();
96+
previousElement = null;
97+
98+
}
99+
100+
}
101+
102+
103+
// I handle top-level clicks on the modal.
104+
function handleModalClick( event ) {
105+
106+
// If the user is clicking directly on the backdrop of the modal, let's
107+
// consider this a request to close the modal (a common interaction model).
108+
if ( modal.is( event.target ) ) {
109+
110+
closeModal();
111+
112+
}
113+
114+
}
115+
116+
</script>
117+
118+
</body>
119+
</html>

0 commit comments

Comments
 (0)