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

如何移除react-modal组件的聚焦以解决无障碍检测告警

问题原因

你收到的ANDI告警是因为react-modal默认会给模态框的content根元素自动添加tabIndex="-1"属性,且打开模态框时会自动聚焦到这个元素。该元素属于可聚焦但不会被键盘Tab键遍历到的元素,因此触发了无障碍规则告警。你之前添加的属性没有生效,是因为react-modal内部会强制覆盖根元素的相关属性。

解决方法

通过react-modal自带的配置项就能直接解决,修改你的Modal组件传参即可:

  1. 禁用打开模态框时自动聚焦根元素的逻辑
  2. 移除根元素默认的tabIndex属性,让其本身不可聚焦
  3. 可选优化:补充关闭按钮的无障碍属性,避免其他无障碍告警

修改后的核心代码如下:

import Modal from 'react-modal';
import React, { useState, useEffect, useCallback } from 'react';

type TProps = {
  isModalOpen: boolean;
  modalContent?: any;
  children?: any;
  toggleModal: () => void;
  render?: () => any;
  allowOverflow?: boolean;
  width?: string;
  height?: string;
  maxHeight?: string;
  maxWidth?: string;
  className?: string;
};

export const CustomModal = (props:TProps) => {
  const [isModalOpen, toggleModal] = useState<boolean>(props.isModalOpen);

  const defaultStyle = {
    content: {
      top            : '50%',
      left           : '50%',
      right          : 'auto',
      bottom         : 'auto',
      marginRight    : '-40%',
      transform      : 'translate(calc(-37% - 0.5px), calc(-40% - 0.1px))',
      width          : props.width || 'fit-content',
      maxWidth       : props.maxWidth || '600px',
      height         : props.height || '97%',
      boxShadow      : '0px -1px 16px -9px rgba(0,0,0,0.4)',
      padding        : '0px',
      inset          : '40.3% auto auto 50%',
      overflow       : `${props.allowOverflow ? 'visible' : 'auto'}`,
      maxHeight      : props.maxHeight || '97%'
    }
  };

  const handleExit = useCallback(() => {
    toggleModal(false);
    props.toggleModal()
  }, [props])

  // 关闭按钮支持键盘触发
  const handleCloseKeyDown = useCallback((e: React.KeyboardEvent) => {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      handleExit();
    }
  }, [handleExit])

  useEffect(() => {
    toggleModal(props.isModalOpen);
  }, [props.isModalOpen])

  // 避免每次渲染重复执行setAppElement
  useEffect(() => {
    Modal.setAppElement(document.body)
  }, [])

  return (
    <React.Fragment>
      <Modal
        style={defaultStyle}
        isOpen={isModalOpen}
        onRequestClose={handleExit}
        shouldCloseOnOverlayClick={true}
        {/* 新增以下两个配置解决告警 */}
        shouldFocusAfterOpen={false}
        contentElementProps={{ tabIndex: undefined }}
        {/* 保留关闭时焦点回退到触发元素的逻辑,符合无障碍规范 */}
        shouldReturnFocusAfterClose={true}
      >
        <div className={`content-container ${props.className ? props.className : ''}`}
             data-testid={`customModalContent`}>
          <div className='exit-button-container'>
            <i className='fas fa-times'
              role="button"
              tabIndex={0}
              onKeyDown={handleCloseKeyDown}
              data-testid={`customModalCloseButton`}
              onClick={handleExit}/>
          </div>
          {(props.isModalOpen || isModalOpen) && props.modalContent && React.createElement(props.modalContent)}
          {(props.isModalOpen || isModalOpen) && props.render && props.render()}
          {props.children || <></>}
        </div>
        
    </Modal>
    </React.Fragment>
  )
}

配置说明

  • shouldFocusAfterOpen={false}:禁用react-modal默认的打开模态框时自动聚焦根元素的逻辑,你可以自行设置模态框内部第一个可交互元素为初始聚焦点,符合无障碍规范
  • contentElementProps={{ tabIndex: undefined }}:覆盖react-modal默认给content根元素添加的tabIndex="-1"属性,让根元素本身不可聚焦,不会再触发ANDI的告警

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 00:27:03