如何使用jQuery实现方向键聚焦相邻ul列表的首个元素
修复后实现逻辑说明
核心调整了左右方向键的判断逻辑,先识别当前聚焦链接是否为所在列表的首项,再匹配相邻列表的首项完成跳转,原有单个列表内的上下导航逻辑保留。
完整修改后代码
// 左右方向键导航功能 $('.someclass a').keydown(function(e){ // 只监听上下左右方向键,其他按键不处理 if ([37,38,39,40].indexOf(e.keyCode) == -1) { return; } var link = $(this); // 获取当前链接所在的ul var currentUl = link.closest('ul.someulclass'); // 获取当前链接所在li是父ul下的第几个元素 var currentLiIndex = link.parent('li').index(); // 所有同层级的ul列表集合 var allUl = $('.someulclass'); // 当前ul在所有列表中的索引 var currentUlIndex = allUl.index(currentUl); switch(e.keyCode) { case 37: // 左箭头 e.preventDefault(); e.stopPropagation(); // 仅当当前是所在ul的第一个元素时触发跨列表跳转 if(currentLiIndex === 0){ var targetUlIndex = currentUlIndex === 0 ? allUl.length - 1 : currentUlIndex - 1; allUl.eq(targetUlIndex).find('li.someclass a').first().focus(); }else{ // 不是首项的话跳转到当前列表的上一个元素 link.parent('li').prev('li').find('a').first().focus(); } break; case 38: // 上箭头 var dropdown = link.parent('li').find('.truist-secondary-menu'); if(dropdown.length > 0){ e.preventDefault(); e.stopPropagation(); dropdown.find('a').filter(':visible').first().focus(); }else{ // 无二级菜单时跳转到当前列表上一个元素,到首项后跨列表 if(currentLiIndex === 0){ var targetUlIndex = currentUlIndex === 0 ? allUl.length - 1 : currentUlIndex - 1; allUl.eq(targetUlIndex).find('li.someclass a').last().focus(); }else{ link.parent('li').prev('li').find('a').first().focus(); } } break; case 39: // 右箭头 e.preventDefault(); e.stopPropagation(); // 仅当当前是所在ul的第一个元素时触发跨列表跳转 if(currentLiIndex === 0){ var targetUlIndex = currentUlIndex === allUl.length - 1 ? 0 : currentUlIndex + 1; allUl.eq(targetUlIndex).find('li.someclass a').first().focus(); }else{ // 不是首项的话跳转到当前列表的下一个元素 link.parent('li').next('li').find('a').first().focus(); } break; case 40: // 下箭头 var dropdown = link.parent('li').find('.menu'); if(dropdown.length > 0){ e.preventDefault(); e.stopPropagation(); dropdown.find('a').filter(':visible').first().focus(); }else{ // 无二级菜单时跳转到当前列表下一个元素,到尾项后跨列表 var currentLiCount = currentUl.find('li.someclass').length; if(currentLiIndex === currentLiCount - 1){ var targetUlIndex = currentUlIndex === allUl.length - 1 ? 0 : currentUlIndex + 1; allUl.eq(targetUlIndex).find('li.someclass a').first().focus(); }else{ link.parent('li').next('li').find('a').first().focus(); } } break; } });
关键修改点说明
- 新增了同层级所有ul的索引判断,准确定位当前列表和目标跳转列表的位置,不受两个ul之间插入的h3标签影响
- 左右方向键触发跨列表跳转的条件修改为当前聚焦链接是所在ul的首项,完全匹配首项之间跳转的需求
- 补充了无二级菜单时上下方向键的列表内首尾循环+跨列表跳转逻辑,符合无障碍操作的常规交互习惯
- 修复了原有代码中ul相邻关系判断错误的问题,跨列表跳转逻辑更稳定
内容的提问来源于stack exchange,提问作者Gracie Sullivan
相关产品推荐
相关产品推荐

