首页 > 解决方案 > 如何修复手风琴磁贴菜单的标签顺序?

问题描述

我正在创建一个瓷砖/手风琴实用程序。单击磁贴时,我将通过将 div 内容附加到最近的第三个 li 元素下方来显示与该磁贴相关的内容,并将手动设置焦点到该 div 内容部分。

我现在可以在 JS 和 CSS 的帮助下实现这个功能:

在此处输入图像描述

但是,可访问性/标签顺序功能被搞砸了。如果我单击 Tile 1 并为其显示内容(div 将附加在第三个 li 元素下方),在使用键盘切换时,链接后焦点应该转到 Tile 2,但它转到 Tile 4(因为DOM 中元素的顺序是按这个顺序排列的,我已经以不同的顺序对元素进行了相对定位以进行显示)。

如果我删除元素的相对定位,外观就会搞砸。

我觉得可以解决的可能解决方案:

  1. 移除元素的相对定位,每次点击图块时,计算顶部、左侧位置值并相对重新对齐图块的位置。

  2. 使用键盘事件,按需要的顺序强制焦点。

有没有人有任何建议可以轻松解决这个问题?

正确的跳格顺序:

  1. 如果点击 Tile 1,

    • 第一个选项卡 - 关注 div 内的链接。
    • 第二个选项卡 - 焦点应移至图块 2。
    • 第三个选项卡 - 焦点应移至图块 3。
    • 第四个选项卡 - 焦点应移至图块 4。
  2. 如果点击了 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>

代码 - https://jsbin.com/rezehepuju/edit?html,css,js,output

标签: javascriptjqueryhtmlcssaccessibility

解决方案


通过使用此解决方案,能够实现预期的跳格顺序。使用绝对、顶部、左侧属性重新定位图块。有效。

$(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>


推荐阅读