我正在创建一个tile / accordion实用程序。 点击图块后,我将通过在最近的第三个li元素下面附加div内容来显示与该图块相关的内容,并将手动将焦点设置到该div内容部分。
我现在可以在JS和CSS的帮助下实现此功能:
但是,可访问性/标签顺序功能搞砸了。如果我点击Tile 1并显示内容(div将附加在第三个li元素下面),使用键盘进行Tab键,在链接后焦点应该转到Tile 2,但它会转到Tile 4(因为DOM中元素的顺序是按顺序排列的,并且我以不同的顺序对元素进行了相对定位以便显示。
如果我删除了元素的相对位置,那么外观就会搞砸了。
我认为可以解决的可能解决方案:
删除元素的相对位置以及每次点击图块,计算顶部,左侧位置值并相对重新对齐图块的位置。
使用键盘事件,按所需顺序强制对焦。
有没有人有任何建议可以轻松解决此问题?
更正标签顺序:
如果单击了Tile 1,
如果单击了Tile 2,
$(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();
});
});
&#13;
.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;
}
&#13;
<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>
&#13;
答案 0 :(得分:0)
如果可能的话,尝试使用tabindex
避免。如果瓷砖是您页面上唯一的东西,那么弄乱tabindex
可能没问题。但是,一旦设置了一个对象的tabindex
,就必须为所有对象设置它。也就是说,您必须完全控制页面上所有内容的Tab键顺序。它变得非常混乱。
Tab键的DOM顺序通常是最佳顺序,所以如果你必须更改Tab键顺序,通常最好更改你的DOM。
但是,请记住,低视力用户,尤其是那些使用放大镜(如ZoomText)的人,可能会对您的标签顺序感到困惑,因为它不一致。放大镜将滚动页面以使焦点保持在视图中。
如果图块1已打开,则订单为:
如果图块2已打开,则订单为:
如果图块3已打开,则订单为:
屏幕放大镜将以“看似”随机的方式不断地来回移动。在跳到开放区域之前,用户不知道焦点是否会在瓷砖上移动。
这不能回答你原来的问题(虽然tabindex
是一种答案),但希望从可访问性的角度提供一些思考的食物。
答案 1 :(得分:0)
使用此解决方案能够实现预期的标签顺序。使用绝对,顶部,左侧属性重新定位切片。它奏效了。
$(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();
});
});
&#13;
.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;
}
&#13;
<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>
&#13;