2016-01-21 129 views
0

我目前使用這個腳本在一個WordPress主題我的下拉菜單項:http://jsfiddle.net/i_like_robots/6JbtX/鍵盤可以使用導航功能

$(function() 
{ 
var $dropdowns = $('li.dropdown'); // Specifying the element is faster for older browsers 

/** 
* Mouse events 
* 
* @description Mimic hoverIntent plugin by waiting for the mouse to 'settle' within the target before triggering 
*/ 
$dropdowns 
    .on('mouseover', function() // Mouseenter (used with .hover()) does not trigger when user enters from outside document window 
    { 
     var $this = $(this); 

     if ($this.prop('hoverTimeout')) 
     { 
      $this.prop('hoverTimeout', clearTimeout($this.prop('hoverTimeout'))); 
     } 

     $this.prop('hoverIntent', setTimeout(function() 
     { 
      $this.addClass('hover'); 
     }, 250)); 
    }) 
    .on('mouseleave', function() 
    { 
     var $this = $(this); 

     if ($this.prop('hoverIntent')) 
     { 
      $this.prop('hoverIntent', clearTimeout($this.prop('hoverIntent'))); 
     } 

     $this.prop('hoverTimeout', setTimeout(function() 
     { 
      $this.removeClass('hover'); 
     }, 250)); 
    }); 

/** 
* Touch events 
* 
* @description Support click to open if we're dealing with a touchscreen 
*/ 
if ('ontouchstart' in document.documentElement) 
{ 
    $dropdowns.each(function() 
    { 
     var $this = $(this); 

     this.addEventListener('touchstart', function(e) 
     { 
      if (e.touches.length === 1) 
      { 
       // Prevent touch events within dropdown bubbling down to document 
       e.stopPropagation(); 

       // Toggle hover 
       if (!$this.hasClass('hover')) 
       { 
        // Prevent link on first touch 
        if (e.target === this || e.target.parentNode === this) 
        { 
         e.preventDefault(); 
        } 

        // Hide other open dropdowns 
        $dropdowns.removeClass('hover'); 
        $this.addClass('hover'); 

        // Hide dropdown on touch outside 
        document.addEventListener('touchstart', closeDropdown = function(e) 
        { 
         e.stopPropagation(); 

         $this.removeClass('hover'); 
         document.removeEventListener('touchstart', closeDropdown); 
        }); 
       } 
      } 
     }, false); 
    }); 
} 

}); 

不過,我需要這些物品是鍵盤訪問。

任何人都可以指向正確的方向嗎?

謝謝!

回答

0

這個問題的答案是使用的focusIn和事件的內容處理程序:

$dropdowns 
.on('focusin', function() // Mouseenter (used with .hover()) does not trigger when user enters from outside document window 
{ 
    var $this = $(this); 

    if ($this.prop('hoverTimeout')) 
    { 
     $this.prop('hoverTimeout', clearTimeout($this.prop('hoverTimeout'))); 
    } 

    $this.prop('hoverIntent', setTimeout(function() 
    { 
     $this.addClass('hover'); 
    }, 250)); 
}) 
.on('focusout', function() 
{ 
    var $this = $(this); 

    if ($this.prop('hoverIntent')) 
    { 
     $this.prop('hoverIntent', clearTimeout($this.prop('hoverIntent'))); 
    } 

    $this.prop('hoverTimeout', setTimeout(function() 
    { 
     $this.removeClass('hover'); 
    }, 250)); 
}); 
1

您正在嘗試以實施像一個Chimera的用戶界面模式。你有一個單一的元素(頂級菜單項),試圖成爲一個鏈接和一個菜單項(與子菜單)。使這種用戶體驗易於使用並且易於使用是非常困難的。

如果您採用@ tom-usborne建議的操作,只需打開focusinfocusout上的菜單,那麼僅鍵盤用戶將不得不通過所有下拉菜單中的每個菜單項進行選項卡選項卡。想象一下,史蒂文霍金不得不使用他的臉頰肌肉多次按下tab鍵!不太好用。

另一種方法 - 比如實施ARIA authoring guidelines for menu interaction意味着頂級項目的鏈接根本無法訪問(因爲回車鍵會打開菜單而不是點擊鏈接)。

但是,如果你只是實現ARIA模式,那麼你會發現在iOS上,菜單不能與之交互。我推薦一種混合方式,將頂層鏈接移動到菜單中,使用正常的單擊(或觸摸或鼠標懸停)將菜單切換爲打開和關閉,然後打開後,可以通過菜單中的所有鏈接進行選項卡。這種方法在所有設備上都能正常工作。