我有一个部分,我隐藏了点击时显示的div。我想要实现的是可访问性合规性,如果我选中并打开其中一个部分,它将标记该部分的内部内容,然后返回到最初停止的位置。
EG。如果我选中并打开第1部分,我希望能够标记第1部分的内部内容,然后返回打开第2部分的按钮,依此类推......
我用我的html /脚本创建了一个小提琴 https://jsfiddle.net/rjvw915r/10/
HTML示例:
<div id="dropdown-menus">
<div id="section1-drop" class="drop-section hidden-panel">
<a href="#">Link 1</a>
<a href="#">Link 2</a>
</div>
<div id="section2-drop" class="drop-section hidden-panel">
<a href="#">Link 1</a>
<a href="#">Link 2</a>
</div>
</div>
<ul id="dropdown-links" class="menu main-tabs">
<li>
<a class="panel-btn"
href="javascript:dropMenu('section1');"
id="drop-link-section1">section 1</a>
</li>
<li>
<a class="panel-btn"
href="javascript:dropMenu('section2');"
id="drop-link-section2">section 2</a>
</li>
</ul>
JavaScript的:
function dropMenu(menusection) {
if ( !($('#dropdown-menus #' + menusection + '-drop').is(':hidden')) ) {
// Select panel is open. Closes the panel.
$('#dropdown-menus #' + menusection + '-drop').slideUp(500);
$('#dropdown-menus #' + menusection + '-drop').removeClass('active');
$('a#drop-link-' + menusection).removeClass('active');
// Scroll to top of buttons.
var aid = $("#dropdown-links");
$('html,body').animate({scrollTop: aid.offset().top-480},400,function(){});
} else if ( $('#dropdown-menus .drop-section').hasClass('active')
&& $('#dropdown-menus #' + menusection + '-drop').is(':hidden') ) {
// Another panel is open.
// Closes currently open panel and opens selected panel.
$('.menu a.active').removeClass('active');
$('#dropdown-menus .active').slideUp(500,function(){
$('#dropdown-menus #' + menusection + '-drop').slideDown(500);
$('#dropdown-menus #' + menusection + '-drop').addClass('active');
$('a#drop-link-' + menusection).addClass('active');
}).removeClass('active');
// Scroll to top of panel.
var aid = $("#dropdown-menus");
$('html,body').animate({scrollTop: aid.offset().top-155},400,function(){});
} else {
// No panel currently open. Opens selected panel.
$('#dropdown-menus #' + menusection + '-drop').slideDown(500);
$('#dropdown-menus #' + menusection + '-drop').addClass('active');
$('a#drop-link-' + menusection).addClass('active');
// Scroll to top of panel.
var aid = $("#dropdown-menus");
$('html,body').animate({scrollTop: aid.offset().top-155},400,function(){});
}
}
谢谢!
答案 0 :(得分:0)
单击链接或按下输入时,您可以使用click
事件执行javascript操作。
<div id="dropdown-menus">
<div id="section1-drop" class="drop-section hidden-panel">
<a href="#">Link 1</a>
<a href="#">Link 2</a>
</div>
<div id="section2-drop" class="drop-section hidden-panel">
<a href="#">Link 3</a>
<a href="#">Link 4</a>
</div>
</div>
<ul id="dropdown-links" class="menu main-tabs">
<li>
<a class="panel-btn"
data-section="section1-drop"
id="drop-link-section1">section 1</a>
</li>
<li>
<a class="panel-btn"
data-section="section2-drop"
id="drop-link-section2">section 2</a>
</li>
</ul>
上面,我删除了href
属性并添加了一个data-section
元素,该元素指定了此链接激活的部分。这更具语义性和可读性,现在我们可以在jQuery中设置我们的处理程序。
定义焦点处理程序:
// Setup the focus handler for the root links
$('.panel-btn').on('click', function(e) {
var link = $(this);
var section = link.attr('data-section');
// Pass in the current link and the section name to dropMenu
dropMenu($(this), section);
});
我已经清理了你的下拉菜单功能,以澄清正在发生的事情
function dropMenu(link, menusection) {
// Get the section specified by the menusection id
var section = $('#' + menusection);
// Get the open section by checking for the active class
var openSection = $('#dropdown-menus').find('.drop-section.active');
// Anonymous function for activating a section and focussing the
// first link within the section
var showSection = function() {
// Slide the section into view
section.slideDown(500).addClass('active');
// Focus the first link in the section.
section.find('a').first().focus();
}
// If there is a section open, we want to slide it up first,
// then call showSection when that has completed.
if(openSection.length > 0) {
// If the open section is the one that was clicked, we want
// to simply close that section rather than open another
if(openSecion[0] === section[0]) {
openSection.slideUp(500).removeClass('active');
}
else {
openSection.slideUp(500, showSection).removeClass('active');
}
}
// Otherwise, we can just show the section straight away.
else {
showSection();
}
}
这一切都非常标准,但您现在需要处理各部分之间的移动,就像您希望本地使用Tab键一样。问题是,由于您的“drop sections”位于根链接之上,因此drop节中最后一个链接的tabbing将始终返回到第1节,因为这是文档中的下一个tabbable元素。为了防止这种情况,我们需要解决一些默认功能并实现我们自己的功能。
首先,您需要配置keydown
处理程序以在发生之前捕获标签
// Setup a keydown handler to handle tabbing on section links
$('.drop-section').on('keydown', 'a', function(e) {
if(e.keyCode === TAB_KEY) {
var link = $(this);
// Flag determins whether to prevent default tab behaviour
var preventDef = false;
// Travel to previous link on SHIFT + TAB
if(e.shiftKey) {
preventDef = travelPrevious(link);
}
// Travel to next link on TAB
else {
preventDef = travelNext(link);
}
// Prevent default focus behaviour
if(preventDef) {
e.preventDefault();
}
}
});
然后我们需要处理下一个标签的功能,以及上一个标签
// Handles travelling to the next link
function travelNext(link) {
var next = link.next();
if(next.length > 0) {
// Continue with default behaviour of moving to next link
return false;
}
// Drop section parent ID
var parentId = link.parents('.drop-section').attr('id');
// Root link whose data-section attribute matches parent ID
var rootLink = $('.panel-btn[data-section=' + parentId + ']').parent();
// Next root link to move to.
var nextLink = rootLink.next().find('a');
// Focus on the next root link, which will fire dropMenu for
// the next section.
nextLink.focus();
// Prevent default behaviour
return true;
}
function travelPrevious(link) {
var prev = link.prev();
if(prev.length > 0) {
// Continue with default behaviour of moving to previous link
return false;
}
// Drop section parent ID
var parentId = link.parents('.drop-section').attr('id');
// LI container for Root link whose data-section attribute matches parent ID
var rootLink = $('.panel-btn[data-section=' + parentId + ']').parent();
// Previous root link to move to.
var prevLink = rootLink.prev().find('a');
// Focus on the previous root link, which will fire dropMenu for
// the previous section.
prevLink.focus();
// Prevent default behaviour
return true;
}
这仍然不是一个完整的解决方案,因为它无法处理所有部分的结束或开始。这应该是一个开始,我相信它会回答你的第一个问题。如果你有其他问题,你应该单独问他们。
这是一个小提琴的例子 https://jsfiddle.net/rjvw915r/17/
更新
如果您的链接在drop-section中以非标准方式包含,则上述方法将无法正常工作,因为它使用查找直接兄弟姐妹的next
和prev
函数。如果每个a
标记都包含在div
或li
包装中,则它们没有直接的兄弟。
我们可以通过回顾已知的父元素并通过选择器查找所有兄弟元素来解决这个问题。在keydown函数中,我们将添加一些额外的代码来检索这些元素,并将它们传递给travel函数。
$('.drop-section').on('keydown', 'a', function(e) {
if(e.keyCode === TAB_KEY) {
var link = $(this);
// Retrieve all available links within the parent.
var linkCollection = link.parents('.drop-section').find('a');
...
在每个旅行功能中,我们都会在
中传递这些链接preventDef = travelPrevious(link, linkCollection);
...
preventDef = travelNext(link, linkCollection);
通过查找当前链接的索引,我们可以确定它之前或之后是否有任何兄弟姐妹。
在travelNext
函数中,我们检查后面是否有任何链接
// Find where the current link sits within the collection
var linkIndex = linkCollection.index(link);
var nextIndex = linkIndex + 1;
if(nextIndex < linkCollection.length) {
// Continue with default behaviour of moving to next link.
return false;
}
在travelPrevious
函数中,我们检查是否有任何链接
// Find where the current link sits within the collection
var linkIndex = linkCollection.index(link);
var nextIndex = linkIndex - 1;
if(nextIndex >= 0) {
// Continue with default behaviour of moving to previous link
return false;
}
请参阅更新的小提琴https://jsfiddle.net/rjvw915r/18/