【问题标题】:How do I get a screen reader to correctly say 'button expanded' when aria-expanded is true当 aria-expanded 为真时,如何让屏幕阅读器正确说出“按钮已扩展”
【发布时间】:2019-05-31 16:52:00
【问题描述】:

我正在努力使我们的手风琴可以通过 aria-expanded 等 aria 标签访问。当单击手风琴触发器标题或按下键盘上的“返回”按钮时,我正确地获得了 aria-expanded 更改的值。出于某种原因,虽然我用来测试的 ChromeVox 最初只会说“按钮折叠”,但一旦点击后值发生变化,就不会说“按钮展开”。

我查看了其他网站上的示例,例如 https://www.w3.org/TR/wai-aria-practices/examples/accordion/accordion.html,ChromeVox 可以正确读取 aria-expanded 的两种状态,所以我认为这是我的代码结构导致 ChromeVox 无法发布“展开”状态。

这是一个手风琴部分的示例:

<div class="accordion-section">

    <button tabIndex="0" id="rules_list" class="accordion" aria-expanded="false" aria-controls="sectRules">
        <span class="title">Rules</span>
    </button>

    <div class="content" role="region" id="sectRules" aria-labledby="rules_list">

        <h4>What rules must all visitors follow?</h4>

        <ul class="list">
            <li style="list-style-type:disc; border-top:0px; margin-bottom:0px; padding-bottom:0px; padding-top:10px; overflow:visible;">rule 1</li>
            <li style="list-style-type:disc; border-top:0px; margin-bottom:0px; padding-bottom:0px; padding-top:10px; overflow:visible;">rule 2</li>
            <li style="list-style-type:disc; border-top:0px; margin-bottom:0px; padding-bottom:0px; padding-top:10px; overflow:visible;">rule 3 etc..</li>
        </ul>

    </div>

</div>

相关的js是:

/* Generic Accordion */
$('.accordion .title').click(function() {
    $(this).parent().parent().children('.content').toggle();
    $(this).toggleClass('open');

    $(this).hasClass("open") ? $(this).parent().attr("aria-expanded", "true") : $(this).parent().attr("aria-expanded", "false");
});

/* Adding support for keyboard */
$('.accordion').on('keydown', function(e) {
    if (/^(13|32)$/.test(e.which)) {
        e.preventDefault();
        $(this).find('.title').click();
    }
});

相关的CSS是:

.accordion + .content {
    display: none;
    margin-top: 10px;
    padding: 10px;
}

.accordion + .content.open {
    display: block;
    background-color: white;
}

我很茫然,任何帮助将不胜感激。

【问题讨论】:

    标签: jquery accessibility accordion wai-aria screen-readers


    【解决方案1】:

    我赞同brennanyoung 关于您使用span 元素的方式以及为什么这可能是您的代码无法按预期工作的原因。

    在我看来,您确实应该考虑使用button 元素来切换内容,因为这样可以避免一些额外的工作,例如:

    • 确保 span 覆盖整个按钮,以防止单击按钮会导致任何结果(大声说听起来很奇怪),
    • 处理聚焦span
    • 确保span 正确地像button 一样工作(点击、按下和其他button 相关事件)。

    此外,在您的代码中以编程方式触发 click 事件暗示可以做一些更简单的事情。

    hidden + aria-labelledby

    我倾向于通过在要切换的内容上使用hidden attribute 和在切换它的按钮上的aria-expanded 来使其尽可能简单。

    Collapsible Sections of the "Inclusive components book" 如果您需要,Heydon Pickering 是一本非常好的读物……嗯,可折叠部分。其实整本书都很棒,如果你还没有读过它,你不会浪费时间。

    hidden 属性由屏幕阅读器正确处理,并将在视觉上和可访问性树中隐藏元素。您可以在几乎任何最新的网络浏览器 (https://caniuse.com/#search=hidden) 上使用它,这使它成为避免与类和 CSS display 属性混淆的好选择。

    如果你想在内容上使用aria-labelledby(顺便说一下,你的代码中缺少一个“L”)(你应该,因为你将它声明为一个区域),使用@ 987654341@ 文本作为标签工作正常。

    但是,如果您打算使用描述操作的文本(例如“显示规则”或“隐藏规则”,具体取决于状态),那么这不再相关,您将不得不使用另一个元素作为此地标的标签。代码中的 h4 元素似乎可以完成这项工作,给它一个 id 将使屏幕阅读器更容易识别该区域。

    示例

    我冒昧地将您提供的示例重写为仅使用纯 JS,并进行了我提到的小调整。可测试here

    <div class="accordion-section" id="accordion-1">
    
        <button id="rules-list" class="rules-toggle" aria-expanded="true" aria-controls="sect-rules">
            <span>Rules</span>
        </button>
    
        <section role="region" class="content" id="sect-rules" aria-labelledby="rules-list-title">
    
            <h4 id="rules-list-title">What rules must all visitors follow?</h4>
    
            <ul class="list">
                <li>rule 1</li>
                <li>rule 2</li>
                <li>rule 3</li>
            </ul>
    
        </section>
    
    </div>
    
    const myButton = document.querySelector('#accordion-1 .rules-toggle');
    myButton.addEventListener('click', toggleRules);
    
    function toggleRules(evt) {
      const button = evt.currentTarget;
      const accordionSection = button.parentElement;
      const content = accordionSection.querySelector('.content');
    
      if ('hidden' in content.attributes) {
        content.removeAttribute('hidden');
        button.setAttribute('aria-expanded', true);
      } else {
        content.setAttribute('hidden', true);
        button.setAttribute('aria-expanded', false);
      }
    }
    
    .rules-toggle + .content {
      margin-top: 10px;
      padding: 10px;
      background-color: white;
    }
    
    .list li {
      list-style-type: disc;
      border-top: 0;
      margin-bottom: 0;
      padding-bottom: 0;
      padding-top: 10px;
      overflow: visible;
    }
    

    【讨论】:

      【解决方案2】:

      您将点击处理程序放在跨度上,而不是按钮上?这似乎不对,并且可能是问题的原因,因为aria-expanded 位于按钮上。

      Voiceover 可能在事件目标上寻找aria-expanded,即span,而不是按钮。当然它没有找到它。

      这可以解释为什么它会在按钮获得焦点时宣布状态,而不是在您单击它时。

      因此,请检查向按钮添加点击而不是跨度是否会为您提供所需的结果。如果这样做,您可以跳过toggle() 中的parent() 步骤之一。

      此外,我会在.content 上设置aria-expanded,并使其与按钮上的aria-expanded 属性保持同步。

      【讨论】:

      • 顺便说一句,当我看到您的内容区域由按钮元素标记时,我抬起了眉毛。这似乎不对,尽管我怀疑这是您的问题的原因。
      • 将 aria-expanded 也放在 .content 上是否有意义?我猜按钮上的 aria-controls 应该足够了。我可以看到我们为什么要这样做的原因,但是,有没有 aria-expanded 也用于受控元素的示例?
      • 我倾向于但 aria-expanded 两者。有一些 w3c 示例可以做到这一点(有些则没有)。
      【解决方案3】:

      这是我的最终解决方案,适用于多个部分:

      ````
         let elementsArray = document.querySelectorAll(".rules-toggle");
      
         elementsArray.forEach(function(elem) {
            elem.addEventListener("click", function (evt) {
              const button = evt.currentTarget;
              const accordionSection = button.parentElement;
              const content = accordionSection.querySelector('.content');
      
             if ('hidden' in content.attributes) {
               content.removeAttribute('hidden');
               button.setAttribute('aria-expanded', true);
             } else {
              content.setAttribute('hidden', true);
              button.setAttribute('aria-expanded', false);
             }
           });
      });
      
      
      

      【讨论】:

        猜你喜欢
        • 2019-01-17
        • 1970-01-01
        • 1970-01-01
        • 2017-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多