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

如何强制元素获得焦点以适配iOS VoiceOver屏幕阅读器

解决iOS VoiceOver交互后指定元素聚焦的方案

问题根因

iOS Safari中DOM的focus方法仅能修改普通页面焦点,和VoiceOver持有的辅助技术焦点是独立的,所以桌面端生效的逻辑在iOS设备上无法同步控制VoiceOver的焦点位置。另外你现有代码里select元素重复定义了两次id属性,可能导致选择器异常,建议先删掉重复的id声明。

可用修复方案

方案1:通用兼容方案

在change事件里加延迟调用,等待iOS原生下拉框收起动画完成后再修改焦点,同时适配VoiceOver的焦点识别逻辑:

handleChange = (e) => {
  const selectEl = document.getElementById("cars");
  // 100-300ms延迟适配iOS下拉框收起动画,避免焦点修改被拦截
  setTimeout(() => {
    selectEl.focus({preventScroll: true});
    // 临时设置aria属性触发VoiceOver主动识别当前元素
    selectEl.setAttribute('aria-selected', 'true');
    setTimeout(() => {
      selectEl.removeAttribute('aria-selected');
    }, 500);
  }, 200);
}

修正后的select标签代码:

<select id="cars" name="cars" onChange={(e) => {this.handleChange(e)}}>
  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
  <option value="mercedes">Mercedes</option>
  <option value="audi">Audi</option>
</select>

方案2:Safari专属优化方案

如果仅需要兼容苹果生态,可以直接调用Safari专属的辅助技术API移动VoiceOver焦点,优先级比普通focus更高:

handleChange = (e) => {
  const selectEl = document.getElementById("cars");
  setTimeout(() => {
    if (window.webkit?.accessibility) {
      window.webkit.accessibility.setFocusedElement(selectEl);
    } else {
      selectEl.focus({preventScroll: true});
    }
  }, 200);
}

注意事项

  • 所有修改焦点的操作必须在用户交互的事件回调链内调用,iOS Safari会直接拦截非用户触发的焦点修改行为
  • 延迟时间不要超过300ms,否则也会被系统判定为非用户交互相关操作被拦截
  • 不要频繁修改焦点位置,避免给屏幕阅读器用户造成使用困扰

内容的提问来源于stack exchange,提问作者j obe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:06:08