]> git.ipfire.org Git - thirdparty/foundation/foundation-sites.git/commitdiff
Fix keyboard access for drilldown 8477/head
authorMarius Olbertz <marius.olbertz@gmail.com>
Mon, 28 Mar 2016 14:38:23 +0000 (16:38 +0200)
committerMarius Olbertz <marius.olbertz@gmail.com>
Mon, 28 Mar 2016 14:38:23 +0000 (16:38 +0200)
Mainly I changed the focused elements to be the `a` tags rather than the `li` tags.
I also added anchors to the menu links in the docs, so it is possible to actually click/space/enter the links to open a new page (or at least change their window's location).
The fact that the links within the menus had only pure `#`es in their `href` did not cover the real-life menu purposes and made proper testing a bit hard.

docs/pages/drilldown-menu.md
js/foundation.drilldown.js

index 57c9d9d2c3b3ad8e0a16a649af39136ce71255d2..0e223dbbae65036856bee9cd3c5a5765b56db880 100644 (file)
@@ -16,13 +16,13 @@ Any `<a>` without a submenu will function like a normal link.
 ```html
 <ul class="vertical menu" data-drilldown>
   <li>
-    <a href="#">Item 1</a>
+    <a href="#Item-1">Item 1</a>
     <ul class="vertical menu">
-      <li><a href="#">Item 1A</a></li>
+      <li><a href="#Item-1A">Item 1A</a></li>
       <!-- ... -->
     </ul>
   </li>
-  <li><a href="#">Item 2</a></li>
+  <li><a href="#Item-2">Item 2</a></li>
 </ul>
 ```
 
@@ -37,40 +37,40 @@ Any `<a>` without a submenu will function like a normal link.
       <li>
         <a href="#">Item 1A</a>
         <ul class="menu">
-          <li><a href="#">Item 1Aa</a></li>
-          <li><a href="#">Item 1Ba</a></li>
-          <li><a href="#">Item 1Ca</a></li>
-          <li><a href="#">Item 1Da</a></li>
-          <li><a href="#">Item 1Ea</a></li>
+          <li><a href="#Item-1Aa">Item 1Aa</a></li>
+          <li><a href="#Item-1Ba">Item 1Ba</a></li>
+          <li><a href="#Item-1Ca">Item 1Ca</a></li>
+          <li><a href="#Item-1Da">Item 1Da</a></li>
+          <li><a href="#Item-1Ea">Item 1Ea</a></li>
         </ul>
       </li>
-      <li><a href="#">Item 1B</a></li>
-      <li><a href="#">Item 1C</a></li>
-      <li><a href="#">Item 1D</a></li>
-      <li><a href="#">Item 1E</a></li>
+      <li><a href="#Item-1B">Item 1B</a></li>
+      <li><a href="#Item-1C">Item 1C</a></li>
+      <li><a href="#Item-1D">Item 1D</a></li>
+      <li><a href="#Item-1E">Item 1E</a></li>
     </ul>
   </li>
   <li>
     <a href="#">Item 2</a>
     <ul class="menu">
-      <li><a href="#">Item 2A</a></li>
-      <li><a href="#">Item 2B</a></li>
-      <li><a href="#">Item 2C</a></li>
-      <li><a href="#">Item 2D</a></li>
-      <li><a href="#">Item 2E</a></li>
+      <li><a href="#Item-2A">Item 2A</a></li>
+      <li><a href="#Item-2B">Item 2B</a></li>
+      <li><a href="#Item-2C">Item 2C</a></li>
+      <li><a href="#Item-2D">Item 2D</a></li>
+      <li><a href="#Item-2E">Item 2E</a></li>
     </ul>
   </li>
   <li>
     <a href="#">Item 3</a>
     <ul class="menu">
-      <li><a href="#">Item 3A</a></li>
-      <li><a href="#">Item 3B</a></li>
-      <li><a href="#">Item 3C</a></li>
-      <li><a href="#">Item 3D</a></li>
-      <li><a href="#">Item 3E</a></li>
+      <li><a href="#Item-3A">Item 3A</a></li>
+      <li><a href="#Item-3B">Item 3B</a></li>
+      <li><a href="#Item-3C">Item 3C</a></li>
+      <li><a href="#Item-3D">Item 3D</a></li>
+      <li><a href="#Item-3E">Item 3E</a></li>
     </ul>
   </li>
-  <li><a href="#"> Item 4</a></li>
+  <li><a href="#Item-4"> Item 4</a></li>
 </ul>
 
 ---
index ee55085bc0fae9a08ef6b1191bf2a83f1b9dbf7e..f716f7efe4f720aafa5367fa6f6dc1b0addd2e06 100644 (file)
@@ -44,9 +44,9 @@ class Drilldown {
    * @private
    */
   _init() {
-    this.$submenuAnchors = this.$element.find('li.is-drilldown-submenu-parent');
-    this.$submenus = this.$submenuAnchors.children('[data-submenu]');
-    this.$menuItems = this.$element.find('li').not('.js-drilldown-back').attr('role', 'menuitem');
+    this.$submenuAnchors = this.$element.find('li.is-drilldown-submenu-parent').children('a');
+    this.$submenus = this.$submenuAnchors.parent('li').children('[data-submenu]');
+    this.$menuItems = this.$element.find('li').not('.js-drilldown-back').attr('role', 'menuitem').find('a');
 
     this._prepareMenu();
 
@@ -113,7 +113,7 @@ class Drilldown {
       // if(e.target !== e.currentTarget.firstElementChild){
       //   return false;
       // }
-      _this._show($elem);
+      _this._show($elem.parent('li'));
 
       if(_this.options.closeOnClick){
         var $body = $('body').not(_this.$wrapper);
@@ -132,9 +132,11 @@ class Drilldown {
    */
   _keyboardEvents() {
     var _this = this;
-    this.$menuItems.add(this.$element.find('.js-drilldown-back')).on('keydown.zf.drilldown', function(e){
+    
+    this.$menuItems.add(this.$element.find('.js-drilldown-back > a')).on('keydown.zf.drilldown', function(e){
+      
       var $element = $(this),
-          $elements = $element.parent('ul').children('li'),
+          $elements = $element.parent('li').parent('ul').children('li').children('a'),
           $prevElement,
           $nextElement;
 
@@ -145,28 +147,33 @@ class Drilldown {
           return;
         }
       });
+
       Foundation.Keyboard.handleKey(e, 'Drilldown', {
         next: function() {
           if ($element.is(_this.$submenuAnchors)) {
-            _this._show($element);
-            $element.on(Foundation.transitionend($element), function(){
-              $element.find('ul li').filter(_this.$menuItems).first().focus();
+            _this._show($element.parent('li'));
+            $element.parent('li').one(Foundation.transitionend($element), function(){
+              $element.parent('li').find('ul li a').filter(_this.$menuItems).first().focus();
             });
+            e.preventDefault();
           }
         },
         previous: function() {
-          _this._hide($element.parent('ul'));
-          $element.parent('ul').on(Foundation.transitionend($element), function(){
+          _this._hide($element.parent('li').parent('ul'));
+          $element.parent('li').parent('ul').one(Foundation.transitionend($element), function(){
             setTimeout(function() {
-              $element.parent('ul').parent('li').focus();
+              $element.parent('li').parent('ul').parent('li').children('a').first().focus();
             }, 1);
           });
+          e.preventDefault();
         },
         up: function() {
           $prevElement.focus();
+          e.preventDefault();
         },
         down: function() {
           $nextElement.focus();
+          e.preventDefault();
         },
         close: function() {
           _this._back();
@@ -174,15 +181,22 @@ class Drilldown {
         },
         open: function() {
           if (!$element.is(_this.$menuItems)) { // not menu item means back button
-            _this._hide($element.parent('ul'));
-            setTimeout(function(){$element.parent('ul').parent('li').focus();}, 1);
+            _this._hide($element.parent('li').parent('ul'));
+            $element.parent('li').parent('ul').one(Foundation.transitionend($element), function(){
+              setTimeout(function() {
+                $element.parent('li').parent('ul').parent('li').children('a').first().focus();
+              }, 1);
+            });            
+            e.preventDefault();
           } else if ($element.is(_this.$submenuAnchors)) {
-            _this._show($element);
-            setTimeout(function(){$element.find('ul li').filter(_this.$menuItems).first().focus();}, 1);
+            _this._show($element.parent('li'));
+            $element.parent('li').one(Foundation.transitionend($element), function(){
+              $element.parent('li').find('ul li a').filter(_this.$menuItems).first().focus();
+            });            
+            e.preventDefault();
           }
         },
         handled: function() {
-          e.preventDefault();
           e.stopImmediatePropagation();
         }
       });
@@ -244,7 +258,7 @@ class Drilldown {
    * Opens a submenu.
    * @function
    * @fires Drilldown#open
-   * @param {jQuery} $elem - the current element with a submenu to open.
+   * @param {jQuery} $elem - the current element with a submenu to open, i.e. the `li` tag.
    */
   _show($elem) {
     $elem.children('[data-submenu]').addClass('is-active');
@@ -256,7 +270,7 @@ class Drilldown {
    * Hides a submenu
    * @function
    * @fires Drilldown#hide
-   * @param {jQuery} $elem - the current sub-menu to hide.
+   * @param {jQuery} $elem - the current sub-menu to hide, i.e. the `ul` tag.
    */
   _hide($elem) {
     var _this = this;
@@ -319,7 +333,7 @@ Drilldown.defaults = {
    * @option
    * @example '<\li><\a>Back<\/a><\/li>'
    */
-  backButton: '<li class="js-drilldown-back"><a>Back</a></li>',
+  backButton: '<li class="js-drilldown-back"><a tabindex="0">Back</a></li>',
   /**
    * Markup used to wrap drilldown menu. Use a class name for independent styling; the JS applied class: `is-drilldown` is required. Remove the backslash (`\`) if copy and pasting.
    * @option
@@ -344,4 +358,4 @@ Drilldown.defaults = {
 // Window exports
 Foundation.plugin(Drilldown, 'Drilldown');
 
-}(jQuery);
+}(jQuery);
\ No newline at end of file