aria Modal - focus trap - last focus

Modal

by ian_smithz

HTML

<section role="main">

      <center>
        <table id="elements" role="grid">
         <tbody>
         <tr role="row">
          <td class="name" role="gridcell" aria-label="Name"><a href="javascript:;"><span>aria-describedat</span></a></td>
          <td class="role" role="gridcell" aria-label="Role Modifiers"><a href="javascript:;"><span>aria-sort</span></a></td>
          <td class="role" role="gridcell" aria-label="Role Modifiers"><a href="javascript:;"><span>aria-rowspan</span></a></td>
          <td class="invisible" role="presentation"></td>
          <td class="invisible" role="presentation"></td>
          <td class="invisible" role="presentation"></td>
          <td class="state" role="gridcell" aria-label="State"><a href="javascript:;"><span>aria-active-descendant</span></a></td>
          <td class="state" role="gridcell" aria-label="State"><a href="javascript:;"><span>aria-grabbed</span></a></td>
          <td class="value" role="gridcell" aria-label="Value"><a href="javascript:;"><span>aria-level</span></a></td>
         </tr>
         <tr role="row">
          <td class="invisible" role="presentation"></td>
          <td class="invisible" role="presentation"></td>
          <td class="invisible" role="presentation"></td>
          <td class="invisible" role="presentation"></td>
          <td class="invisible" role="presentation"></td>
          <td class="invisible" role="presentation"></td>
          <td class="invisible" role="presentation"></td>
          <td class="invisible" role="presentation"></td>
          <td class="invisible" role="presentation"></td>
         </tr>
        </tbody></table>
      </center>
      <h3>Legend</h3>
      <ul id="legend" class="clearfix">
        <li class="name"><div class="icon"></div>Name</li>
        <li class="role"><div class="icon"></div>Role Modifiers</li>
        <li class="state"><div class="icon"></div>State</li>
        <li class="interactive"><div class="icon"></div>Interactive</li>
       ...

CSS

body {
  padding-top: 20px;
  padding-left: 20px;
  background-color: #fff;
  color: #000;
  font-family:Tahoma, Verdana, Arial, sans-serif;
}
h1, h3 {
  text-align:center;
}
h1 {
  font-family: "Temporarium", "Palatino Linotype", "Book Antiqua", Palatino, serif;
  font-size:2.5em;
  text-shadow: 1px 1px 1px rgba(0, 0, 0, 1);
}

h3 {
  margin-top:.25em;
  margin-bottom:.25em;
  font-size: .67em;
}

td a {
  text-decoration: none;
  color:black;
}

.style0
	{text-align:general;
	vertical-align:bottom;
	white-space:nowrap;
	color:windowtext;
	font-size:10.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:Verdana;
	border:none;}
#elements td {
  	font-size:11px;
  	font-weight:normal;
  	font-style:normal;
  	text-decoration:none;
    color: #000;
  	text-align:general;
  	vertical-align:bottom;
  	white-space:normal;
    border-radius: 10px;
    width:5em;
    height: 5em;
    overflow:wrap;
    text-align:center;
    vertical-align:middle;
    border:2px solid black;
  }
  #elements td.invisible {
    border:2px solid transparent;
  }
  table#elements {
    text-align:center;
    min-width:800px;
  }
/* Legend */

ul#legend .icon {
  cursor: pointer;
  font-size: 0.9em;
  margin: 0;
  opacity: 0.8;
  padding: 0;
  overflow: hidden;
  text-align: center;
  position: relative;
  border-radius: 0.5em;
  -o-border-radius: 0.5em;
  -moz-border-radius: 0.5em;
  -webkit-border-radius: 0.5em;
}

ul#legend {
  width:75%;
  color: black;
  margin: 0;
  padding-left: 0;
  list-style: none;
}

ul#legend li {
  float: left;
  font-size:12px;
  width: 24%;
  padding: 0.125em 0;
}

ul#legend .icon {
  height: 1.5em;
  width: 1.5em;
  display: inline-block;
  margin: 0 0.5em;
  vertical-align: middle;
  border:1px solid black;
}

fieldset {
  width:20%;
  display:inline-block;
  border:none;
  font-size:12px;
  vertical-align:top;
  border: 2px solid #eee;
  border-radius:10px;
}

.clearfix:after {
    content: ".";
    display: block;
    clear:...

JavaScript

var preStyles = {
 "line-height": "1.4",
 "font-family": "Monaco, 'Courier New', Courier",
 "font-size": "0.75em",
 "border-top-style": "solid",
 "border-right-style": "solid",
 "border-bottom-style": "solid",
 "border-left-style": "solid",
 "border-top-width": "1px",
 "border-right-width": "1px",
 "border-bottom-width": "1px",
 "border-left-width": "1px",
 "border-top-color": "rgb(153, 153, 153)",
 "border-right-color": "rgb(153, 153, 153)",
 "border-bottom-color": "rgb(153, 153, 153)",
 "border-left-color": "rgb(153, 153, 153)",
 "border-image-source": "initial",
 "border-image-slice": "initial",
 "border-image-width": "initial",
 "border-image-outset": "initial",
 "border-image-repeat": "initial",
 "background-color": "rgb(252, 252, 252)",
 "margin-top": "1em",
 "margin-right": "0px",
 "margin-bottom": "1em",
 "margin-left": "0px",
 "padding-top": "0.5em",
 "padding-right": "0.8em",
 "padding-bottom": "0.5em",
 "padding-left": "0.8em",
 "overflow-x":"scroll"
};

jQuery(document).ready(function () {
  jQuery('td')
    .each(function(index, value) {
      var descText = jQuery('li.' + value.className).text();
      if(descText.length) {
        jQuery(value).attr('aria-label', descText);
      }
    })
    .on('keydown', function (e) {
      var handled = false;
      var keyCode = e.which || e.keyCode;
      var $this = jQuery(this);
      var $nextTd, $nextRow;

      if (e.ctrlKey || e.shiftKey || e.altKey || e.metaKey) {
        return;
      }
      switch(keyCode) {
        case 37: // LEFT
          handled = true;
          $nextTd = $this.prev('td');
          break;
        case 38: // UP
          handled = true;
          $nextRow = $this.parent().prev('tr');
          $nextTd = $nextRow.find('td').eq($this[0].cellIndex);
          break;
        case 39: // RIGHT
          handled = true;
          $nextTd = $this.next('td');
          break;
        case 40: // DOWN
          handled = true;
          $nextRow = $this.parent().next('tr');
         ...