From cb3d8828704a5098f228725f4321a2b70287e72b Mon Sep 17 00:00:00 2001 From: Marius Olbertz Date: Sat, 9 Apr 2016 12:25:49 +0200 Subject: [PATCH] Fixed keyboard interaction for dropdown menu. Fixes behaviour for vertical menus to be correct (switch left/right with up/down compared to horizontal menus). Fixed usage of `e.preventDefault()` to enable opening of links in the menu. --- js/foundation.dropdownMenu.js | 59 ++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/js/foundation.dropdownMenu.js b/js/foundation.dropdownMenu.js index 3f2f1c4ae..06d933e7a 100644 --- a/js/foundation.dropdownMenu.js +++ b/js/foundation.dropdownMenu.js @@ -69,29 +69,32 @@ class DropdownMenu { hasTouch = 'ontouchstart' in window || (typeof window.ontouchstart !== 'undefined'), parClass = 'is-dropdown-submenu-parent'; - if (this.options.clickOpen || hasTouch) { - this.$menuItems.on('click.zf.dropdownmenu touchstart.zf.dropdownmenu', function(e) { - var $elem = $(e.target).parentsUntil('ul', `.${parClass}`), - hasSub = $elem.hasClass(parClass), - hasClicked = $elem.attr('data-is-click') === 'true', - $sub = $elem.children('.is-dropdown-submenu'); + // used for onClick and in the keyboard handlers + var handleClickFn = function(e) { + var $elem = $(e.target).parentsUntil('ul', `.${parClass}`), + hasSub = $elem.hasClass(parClass), + hasClicked = $elem.attr('data-is-click') === 'true', + $sub = $elem.children('.is-dropdown-submenu'); - if (hasSub) { - if (hasClicked) { - if (!_this.options.closeOnClick || (!_this.options.clickOpen && !hasTouch) || (_this.options.forceFollow && hasTouch)) { return; } - else { - e.stopImmediatePropagation(); - e.preventDefault(); - _this._hide($elem); - } - } else { - e.preventDefault(); + if (hasSub) { + if (hasClicked) { + if (!_this.options.closeOnClick || (!_this.options.clickOpen && !hasTouch) || (_this.options.forceFollow && hasTouch)) { return; } + else { e.stopImmediatePropagation(); - _this._show($elem.children('.is-dropdown-submenu')); - $elem.add($elem.parentsUntil(_this.$element, `.${parClass}`)).attr('data-is-click', true); + e.preventDefault(); + _this._hide($elem); } - } else { return; } - }); + } else { + e.preventDefault(); + e.stopImmediatePropagation(); + _this._show($elem.children('.is-dropdown-submenu')); + $elem.add($elem.parentsUntil(_this.$element, `.${parClass}`)).attr('data-is-click', true); + } + } else { return; } + }; + + if (this.options.clickOpen || hasTouch) { + this.$menuItems.on('click.zf.dropdownmenu touchstart.zf.dropdownmenu', handleClickFn); } if (!this.options.disableHover) { @@ -135,20 +138,26 @@ class DropdownMenu { }); var nextSibling = function() { - if (!$element.is(':last-child')) $nextElement.children('a:first').focus(); + if (!$element.is(':last-child')) { + $nextElement.children('a:first').focus(); + e.preventDefault(); + } }, prevSibling = function() { $prevElement.children('a:first').focus(); + e.preventDefault(); }, openSub = function() { var $sub = $element.children('ul.is-dropdown-submenu'); if ($sub.length) { _this._show($sub); $element.find('li > a:first').focus(); + e.preventDefault(); } else { return; } }, closeSub = function() { //if ($element.is(':first-child')) { var close = $element.parent('ul').parent('li'); - close.children('a:first').focus(); - _this._hide(close); + close.children('a:first').focus(); + _this._hide(close); + e.preventDefault(); //} }; var functions = { @@ -156,15 +165,15 @@ class DropdownMenu { close: function() { _this._hide(_this.$element); _this.$menuItems.find('a:first').focus(); // focus to first element + e.preventDefault(); }, handled: function() { - e.preventDefault(); e.stopImmediatePropagation(); } }; if (isTab) { - if (_this.vertical) { // vertical menu + if (_this.$element.hasClass(_this.options.verticalClass)) { // vertical menu if (_this.options.alignment === 'left') { // left aligned $.extend(functions, { down: nextSibling, -- 2.47.2