javascript - 如何修复手风琴磁贴菜单的标签顺序?
问题描述
我正在创建一个瓷砖/手风琴实用程序。单击磁贴时,我将通过将 div 内容附加到最近的第三个 li 元素下方来显示与该磁贴相关的内容,并将手动设置焦点到该 div 内容部分。
我现在可以在 JS 和 CSS 的帮助下实现这个功能:
但是,可访问性/标签顺序功能被搞砸了。如果我单击 Tile 1 并为其显示内容(div 将附加在第三个 li 元素下方),在使用键盘切换时,链接后焦点应该转到 Tile 2,但它转到 Tile 4(因为DOM 中元素的顺序是按这个顺序排列的,我已经以不同的顺序对元素进行了相对定位以进行显示)。
如果我删除元素的相对定位,外观就会搞砸。
我觉得可以解决的可能解决方案:
移除元素的相对定位,每次点击图块时,计算顶部、左侧位置值并相对重新对齐图块的位置。
使用键盘事件,按需要的顺序强制焦点。
有没有人有任何建议可以轻松解决这个问题?
正确的跳格顺序:
如果点击 Tile 1,
- 第一个选项卡 - 关注 div 内的链接。
- 第二个选项卡 - 焦点应移至图块 2。
- 第三个选项卡 - 焦点应移至图块 3。
- 第四个选项卡 - 焦点应移至图块 4。
如果点击了 Tile 2,
- 第一个选项卡 - 关注 div 内的链接。
- 第二个选项卡 - 焦点应该移动到平铺。
- 第三个选项卡 - 焦点应该移动到平铺。
- 第四个选项卡 - 焦点应移至平铺
$(document).ready(function() {
$("#tiles > li").click(function() {
var idVal = $(this).find("a").attr("rel");
dynamicContainerClass = "";
var indexVal = parseInt($(this).attr("rel"));
$(".dynamicContainer").remove();
var id = parseInt($(this).attr("rel"));
var $positionObj = $("#contentDiv").html();
//$('<div class=dynamicContainer aria-live="assertive" tabindex="-1"><div id=' + id + " class=" + dynamicContainerClass + ">" + $positionObj + "</div></div>").insertAfter($(this))
if (indexVal % 3 == 1) {
var next = $(this).next();
var nextCtr = 1;
while (next.hasClass("active") == false) {
next = next.next();
nextCtr++;
if (nextCtr > 12) {
break
}
}
var afterNext = next.next();
var afterNextCtr = 1;
while (afterNext.hasClass("active") == false) {
afterNext = afterNext.next();
afterNextCtr++;
if (afterNextCtr > 12) {
break
}
}
if (afterNext.size() > 0) {
$('<div class=dynamicContainer aria-live="assertive" tabindex="-1"><div id=' + id + " class=" + dynamicContainerClass + ">" + $positionObj + "</div></div>").insertAfter(afterNext)
} else {
if (next.size() > 0) {
$('<div class=dynamicContainer aria-live="assertive" tabindex="-1"><div id=' + id + " class=" + dynamicContainerClass + ">" + $positionObj + "</div></div>").insertAfter(next)
} else {
$('<div class=dynamicContainer aria-live="assertive" tabindex="-1"><div id=' + id + " class=" + dynamicContainerClass + ">" + $positionObj + "</div></div>").insertAfter($(this))
}
}
} else {
if (indexVal % 3 == 2) {
var nextCtr = 1;
var next = $(this).next();
while (next.hasClass("active") == false) {
next = next.next();
nextCtr++;
if (nextCtr > 12) {
break
}
}
if (next.size() > 0) {
$('<div class=dynamicContainer aria-live="assertive" tabindex="-1"><div id=' + id + " class=" + dynamicContainerClass + ">" + $positionObj + "</div></div>").insertAfter(next)
} else {
$('<div class=dynamicContainer aria-live="assertive" tabindex="-1"><div id=' + id + " class=" + dynamicContainerClass + ">" + $positionObj + "</div></div>").insertAfter($(this))
}
} else {
if (indexVal % 3 == 0) {
$('<div class=dynamicContainer aria-live="assertive" tabindex="-1"><div id=' + id + " class=" + dynamicContainerClass + ">" + $positionObj + "</div></div>").insertAfter($(this))
}
}
}
$(".dynamicContainer #" + id).addClass("container-text").attr("tabindex", "-1").focus();
});
});
.tiles-module {
font-size: 12px;
font-family: Arial;
display: block;
width: 292px;
background-color: #e5e2da;
margin: 0 10px;
min-height: 1px;
}
.tiles-module .tiles-header {
font-family: Arial;
font-size: 18px;
margin: 0 0 1px 16px;
color: #6b5e51;
padding-top: 3px;
}
.tiles-module #tiles>li {
float: left;
width: 95px;
height: 89px;
padding: 0;
margin: 0 1px 1px 0;
}
.tiles-module img {
cursor: pointer;
}
.tiles-module .tab-container li a {
background-color: #fff;
border: medium none;
color: #605952;
cursor: pointer;
display: inline-block;
height: 85px;
outline: medium none;
text-decoration: none !important;
width: 91px;
border-right: 2px solid #b6b5b2;
border-bottom: 2px solid #b6b5b2;
}
.tiles-module .tab-container {
margin-left: 4px;
}
ul {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
.tiles-module .dynamicContainer {
position: relative;
top: -3px;
}
.tiles-module .tab-container .container-text {
width: 284px;
float: left;
margin-bottom: 1px;
margin-top: 3px;
}
.tiles-module .container-text {
display: inline-block;
position: relative;
background-color: #FFF;
width: 268px;
}
.container-text {
height: 100px;
text-align: center;
}
.tiles-module .tab-container li a:focus, .tiles-module .tab-container li a:active {
background-color: #B0E9FD;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<body>
<div class="tiles-module">
<div class="tiles-tab">
<div class="tab-container">
<div class="tiles-header">
<h3>Tiles Section</h3>
</div>
<ul id="tiles">
<li class="active" rel="1">
<a href="javascript:void(0);" >
<p>Tile 1</p>
</a>
</li>
<li class="active" rel="2">
<a href="javascript:void(0);" >
<p>Tile 2</p>
</a>
</li>
<li class="active" rel="3">
<a href="javascript:void(0);">
<p>Tile 3</p></a>
</li>
<li class="active" rel="4">
<a href="javascript:void(0);">
<p>Tile 4</p>
</a>
</li>
<li class="active" rel="5">
<a href="javascript:void(0);">
<p>Tile 5</p>
</a>
</li>
<li class="active" rel="6">
<a href="javascript:void(0);">
<p>Tile 6 </p>
</a>
</li>
<li class="active" rel="7">
<a href="javascript:void(0);">
<p>Tile 7 </p>
</a>
</li>
<li class="active" rel="8">
<a href="javascript:void(0);">
<p>Tile 8</p>
</a>
</li>
</ul>
</div>
<div class="ClearAll" style="clear:both;"></div>
</div>
<div id="contentDiv" style="display:none;">This is the tile content <a href="javascript:void(0);">This is link focusable element inside tile content</a></div>
</div>
</body>
解决方案
通过使用此解决方案,能够实现预期的跳格顺序。使用绝对、顶部、左侧属性重新定位图块。有效。
$(document).ready(function() {
$("#tiles > li").click(function() {
var idVal = $(this).find("a").attr("rel");
dynamicContainerClass = "";
var indexVal = parseInt($(this).attr("rel"));
$(".dynamicContainer").remove();
var id = parseInt($(this).attr("rel"));
var $positionObj = $("#contentDiv").html();
var listItems = $("#tiles li");
listItems.each(function(idx, li) {
$(li).css({'position':'','top':'','left':''});
});
//$('<div class=dynamicContainer aria-live="assertive" tabindex="-1"><div id=' + id + " class=" + dynamicContainerClass + ">" + $positionObj + "</div></div>").insertAfter($(this))
if (indexVal % 3 == 1) {
var next = $(this).next();
var positionOne = next.position();
var nextCtr = 1;
while (next.hasClass("active") == false) {
next = next.next();
nextCtr++;
if (nextCtr > 12) {
break
}
}
var afterNext = next.next();
var positionTwo = afterNext.position();
var afterNextCtr = 1;
while (afterNext.hasClass("active") == false) {
afterNext = afterNext.next();
afterNextCtr++;
if (afterNextCtr > 12) {
break
}
}
if (afterNext.size() > 0) {
$('<div class=dynamicContainer aria-live="assertive" tabindex="-1"><div id=' + id + " class=" + dynamicContainerClass + ">" + $positionObj + "</div></div>").insertAfter($(this));
afterNext.css('position','absolute');
afterNext.css('left',positionTwo.left);
afterNext.css('top',positionTwo.top);
next.css('position','absolute');
next.css('left',positionOne.left);
next.css('top',positionOne.top);
} else {
if (next.size() > 0) {
$('<div class=dynamicContainer aria-live="assertive" tabindex="-1"><div id=' + id + " class=" + dynamicContainerClass + ">" + $positionObj + "</div></div>").insertAfter($(this));
next.css('position','absolute');
next.css('left',positionOne.left);
next.css('top',positionOne.top);
} else {
$('<div class=dynamicContainer aria-live="assertive" tabindex="-1"><div id=' + id + " class=" + dynamicContainerClass + ">" + $positionObj + "</div></div>").insertAfter($(this))
}
}
} else {
if (indexVal % 3 == 2) {
var nextCtr = 1;
var next = $(this).next();
var positionOne = next.position();
while (next.hasClass("active") == false) {
next = next.next();
nextCtr++;
if (nextCtr > 12) {
break
}
}
if (next.size() > 0) {
$('<div class=dynamicContainer aria-live="assertive" tabindex="-1"><div id=' + id + " class=" + dynamicContainerClass + ">" + $positionObj + "</div></div>").insertAfter($(this));
next.css('position','absolute');
next.css('left',positionOne.left);
next.css('top',positionOne.top);
} else {
$('<div class=dynamicContainer aria-live="assertive" tabindex="-1"><div id=' + id + " class=" + dynamicContainerClass + ">" + $positionObj + "</div></div>").insertAfter($(this))
}
} else {
if (indexVal % 3 == 0) {
$('<div class=dynamicContainer aria-live="assertive" tabindex="-1"><div id=' + id + " class=" + dynamicContainerClass + ">" + $positionObj + "</div></div>").insertAfter($(this))
}
}
}
$(".dynamicContainer #" + id).addClass("container-text").attr("tabindex", "-1").focus();
});
});
.tiles-module {
font-size: 12px;
font-family: Arial;
display: block;
width: 292px;
background-color: #e5e2da;
margin: 0 10px;
min-height: 1px;
}
.tiles-module .tiles-header {
font-family: Arial;
font-size: 18px;
margin: 0 0 1px 16px;
color: #6b5e51;
padding-top: 3px;
}
.tiles-module #tiles>li {
float: left;
width: 95px;
height: 89px;
padding: 0;
margin: 0 1px 1px 0;
}
.tiles-module img {
cursor: pointer;
}
.tiles-module .tab-container li a {
background-color: #fff;
border: medium none;
color: #605952;
cursor: pointer;
display: inline-block;
height: 85px;
outline: medium none;
text-decoration: none !important;
width: 91px;
border-right: 2px solid #b6b5b2;
border-bottom: 2px solid #b6b5b2;
}
.tiles-module .tab-container {
margin-left: 4px;
}
ul {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
.tiles-module .dynamicContainer {
position: relative;
top: -3px;
}
.tiles-module .tab-container .container-text {
width: 284px;
float: left;
margin-bottom: 1px;
margin-top: 3px;
}
.tiles-module .container-text {
display: inline-block;
position: relative;
background-color: #FFF;
width: 268px;
}
.container-text {
height: 100px;
text-align: center;
}
.tiles-module .tab-container li a:focus, .tiles-module .tab-container li a:active {
background-color: #B0E9FD;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<body>
<div class="tiles-module">
<div class="tiles-tab">
<div class="tab-container">
<div class="tiles-header">
<h3>Tiles Section</h3>
</div>
<ul id="tiles">
<li class="active" rel="1">
<a href="javascript:void(0);" >
<p>Tile 1</p>
</a>
</li>
<li class="active" rel="2">
<a href="javascript:void(0);" >
<p>Tile 2</p>
</a>
</li>
<li class="active" rel="3">
<a href="javascript:void(0);">
<p>Tile 3</p></a>
</li>
<li class="active" rel="4">
<a href="javascript:void(0);">
<p>Tile 4</p>
</a>
</li>
<li class="active" rel="5">
<a href="javascript:void(0);">
<p>Tile 5</p>
</a>
</li>
<li class="active" rel="6">
<a href="javascript:void(0);">
<p>Tile 6 </p>
</a>
</li>
<li class="active" rel="7">
<a href="javascript:void(0);">
<p>Tile 7 </p>
</a>
</li>
<li class="active" rel="8">
<a href="javascript:void(0);">
<p>Tile 8</p>
</a>
</li>
</ul>
</div>
<div class="ClearAll" style="clear:both;"></div>
</div>
<div id="contentDiv" style="display:none;">This is the tile content <a href="javascript:void(0);">This is link focusable element inside tile content</a></div>
</div>
</body>
推荐阅读
- node.js - Node Js找不到模块./build/Release/generator
- pip - 找到缓存后 github 操作 pip 依赖项不起作用
- rust - 提供带有生命周期的惰性静态引用
- mysql - AWS RDS Mysql 5.7 中缺少 help_keywords
- react-native - React Native Drawer 和 Tab 导航
- javascript - Discord倒数计时器机器人将在计时器下降时自行编辑
- spring-boot - 在 Spring Boot 中出现“defaultValidator”错误
- php - SQL中@后如何获取数据
- mysql - 使用池连接访问 MariaDb/Mysql 的 Dart 包
- cakephp - Cakephp如何获得一个月的第一个和最后一个日期时间