You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js Tooltip关闭后iOS Safari VoiceOver首滑无播报问题及解决问询

iOS Safari中Vue.js Tooltip的VoiceOver无障碍问题解析与解决

问题背景

  • Tooltip通过点击/获取焦点触发打开
  • Tooltip包含可读文本内容及关闭按钮
  • 在Tooltip内部使用VoiceOver滑动导航时正常
  • 点击关闭按钮时的操作:
    • 通过v-if将Tooltip从DOM中移除
    • 调用focus()将焦点恢复至触发按钮

问题现象

  • 视觉和代码层面焦点已正确回到触发按钮,但VoiceOver首次滑动无任何播报
  • 第二次滑动才能正常跳转到下一个可访问元素

代码示例

HTML结构

<!-- Trigger -->
<button
  ref="trigger"
  class="trigger"
  @click="openTooltip"
>
  Application moved
</button>

<!-- Tooltip -->
<div
  v-if="showTooltip"
  ref="tooltip"
  role="tooltip"
  class="tooltip"
>
  <p>This application was moved to another job.</p>

  <button
    @click="closeTooltip"
  >
    Close tooltip
  </button>
</div>

<!-- Next focusable element -->
<button class="next">
  Next element
</button>

脚本逻辑

const showTooltip = ref(false);
const trigger = ref(null);

function openTooltip() {
  showTooltip.value = true;
}

function closeTooltip() {
  showTooltip.value = false;

  nextTick(() => {
    // Restore focus to trigger
    trigger.value?.focus();
  });
}

原因分析

这是WebKit/VoiceOver的已知行为:当动态移除DOM元素(如这里的Tooltip)后,VoiceOver的内部导航状态与实际DOM焦点出现不同步。虽然我们通过focus()将DOM焦点设回了触发按钮,但VoiceOver的导航队列仍停留在之前关闭按钮的位置。第一次滑动操作实际上是让VoiceOver的状态追上DOM焦点,因此不会产生播报;第二次滑动才是正常的导航跳转。

推荐解决方案

方案1:用v-show替代v-if保留DOM

将Tooltip的v-if改为v-show,这样Tooltip不会从DOM中移除,仅通过CSS隐藏,避免VoiceOver状态错乱:

<div
  v-show="showTooltip"
  ref="tooltip"
  role="tooltip"
  class="tooltip"
>
  <!-- Tooltip内容 -->
</div>

注意:为避免隐藏的Tooltip干扰焦点导航,可给Tooltip添加tabindex="-1",或在隐藏时将内部按钮的tabindex临时设为-1。

方案2:强制同步VoiceOver焦点状态

在恢复焦点时,先触发blur再立即触发focus,强制VoiceOver更新内部状态:

function closeTooltip() {
  showTooltip.value = false;
  nextTick(() => {
    const triggerEl = trigger.value;
    if (triggerEl) {
      triggerEl.blur();
      triggerEl.focus();
    }
  });
}

方案3:遵循WAI-ARIA规范建立关联

给触发按钮添加aria-describedby属性,与Tooltip建立关联,帮助辅助技术理解二者关系:

<button
  ref="trigger"
  class="trigger"
  @click="openTooltip"
  :aria-describedby="showTooltip ? 'tooltip-id' : null"
>
  Application moved
</button>

<div
  v-if="showTooltip"
  ref="tooltip"
  id="tooltip-id"
  role="tooltip"
  class="tooltip"
>
  <!-- Tooltip内容 -->
</div>

这种关联能减少辅助技术状态不同步的概率,同时提升整体无障碍体验。

内容的提问来源于stack exchange,提问作者Dhulipati Sree Mallika Bhargav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 19:13:08