reactjs - Focus Trap React 和 2 个弹出窗口中的一些组件
问题描述
我有 2 个弹出窗口(我在2个弹出窗口中重用 了 CloseButton(组件)和Modal(组件))并且根本需要做焦点陷阱。我会回答 4 个更好的方法。
- 1个弹出屏幕,组件:ModalLogin- Modal - CloseButton。
我读到了一些钩子:useRef()和forwardRef(props, ref) 但我不明白为什么它在我的情况下不起作用。我正在努力寻找解决方案。我需要帮助 :)
在 ModalLogin 中,我尝试做一个焦点陷阱。为此,我标记了当移动到 1 和最后一个元素时焦点应该发生的事情。我需要传递通过 Modal-CloseButton 获得的 ref 挂钩。我读到您不能只将 refs 转移到功能组件。我尝试在传输它的必要组件中使用 forwardref 钩子,这就是我所做的:
所有没有焦点陷阱和钩子的链接!。
https://github.com/j3n4r3v/ligabank-credit/blob/master/src/components/form-login/modal-login.jsx [模态登录完整]
const ModalLogin = () => {
const topTabTrap* = useRef();
const bottomTabTrap* = useRef();
const firstFocusableElement = useRef();
const lastFocusableElement = useRef();
useEffect(() => {
const trapFocus = (event) => {
if (event.target === topTabTrap.current) {
lastFocusableElement.current.focus()
}
if (event.target === bottomTabTrap.current) {
firstFocusableElement.current.focus()
}
}
document.addEventListener('focusin', trapFocus)
return () => document.removeEventListener('focusin', trapFocus)
}, [firstFocusableElement, lastFocusableElement])
return (
<Modal onCloseModal={() => onCloseForm()} ref={lastFocusableElement}>
<form >
<span ref={topTabTrap} tabIndex="0" />
<Logo />
<Input id="email" ref={firstFocusableElement} />
<Input id="password" />
<Button type="submit" />
<span ref={bottomTabTrap} tabIndex="0"/>
</form>
</Modal>
);
};
https://github.com/j3n4r3v/ligabank-credit/blob/master/src/components/modal/modal.jsx [模态完整]
const Modal = forwardRef(({ props, ref }) => {
const { children, onCloseModal, ...props } = props;
const overlayRef = useRef();
useEffect(() => {
const preventWheelScroll = (evt) => evt.preventDefault();
document.addEventListener('keydown', onEscClick);
window.addEventListener('wheel', preventWheelScroll, { passive: false });
return () => {
document.removeEventListener('keydown', onEscClick);
window.removeEventListener('wheel', preventWheelScroll);
};
});
const onCloseModalButtonClick = () => {
onCloseModal();
};
return (
<div className="overlay" ref={overlayRef}
onClick={(evt) => onOverlayClick(evt)}>
<div className="modal">
<CloseButton
ref={ref}
onClick={() => onCloseModalButtonClick()}
{...props}
/>
{children}
</div>
</div>
);
});
https://github.com/j3n4r3v/ligabank-credit/blob/master/src/components/close-button/close-button.jsx [CloseButton full]
const CloseButton = forwardRef(({ props, ref }) => {
const {className, onClick, ...props} = props;
return (
<button className={`${className} close-button`}
onClick={(evt) => onClick(evt)}
tabIndex="0"
ref={ref}
{...props}
>Close</button>
);
});
现在我有很多错误,例如:1 - 无法读取未定义的属性(读取“孩子”) - 模态,2 - ... className undefined in CloseButton 等。
- 2个弹出屏幕,组件:模态(在1个弹出窗口中重用)-InfoSuccess- CloseButton(在1个弹出窗口中重用)
我只有 1 个交互式元素 - 按钮(tabindex),仅此而已。现在我对带有焦点陷阱的 2 个弹出窗口一无所知((
https://github.com/j3n4r3v/ligabank-credit/blob/master/src/components/success-modal/success-modal.jsx [SuccessModal 完整]
const SuccessModal = ({ className, onChangeVisibleSuccess }) => {
return (
<Modal onCloseModal={() => onChangeVisibleSuccess(false)}>
<InfoSuccess className={className} />
</Modal>
);
};
https://github.com/j3n4r3v/ligabank-credit/blob/master/src/components/info-block/info-block.jsx [信息块完整]
const InfoBlock = ({ className, title, desc, type }) => {
return (
<section className={`info-block ${className} info-block--${type}`}>
<h3 className="info-block__title">{title}</h3>
<p className="info-block__desc">{desc}</p>
</section>
);
};
const InfoSuccess = ({ className }) => (
<InfoBlock
title="Спасибо за обращение в наш банк."
desc="Наш менеджер скоро свяжется с вами по указанному номеру телефона."
type="center"
className={className}
/>
);
我知道 3 in 1 = 1 组件,并且在使用 Focus-Trap 的弹出窗口中没有问题。但我想了解我的案例,它是否真实存在以及最佳实践。
解决方案
推荐阅读
- python - 从我的服务器下载文件以将服务器跳转到我的笔记本电脑
- reactjs - Microsoft Edge isPersonal SavePersonalAndPaymentData 刹车 React 应用
- c# - 从 HttpRequestMessage 获取 Route 参数
- c# - 如何通过解析剃刀助手中的表达式来获取复杂(嵌套)属性的值?
- android - 如何将手机上本地文件的文件路径传递给我的应用程序(android)?
- javascript - WordPress 页面自行滚动并开始抖动
- r - 老鼠包错误:cor(xobs [,keep,drop = FALSE],use =“all.obs”):'x'是空的
- python - 如何增加累积最大值
- java - 如何修复'第 1 行被截断;从 csv 文件加载数据时,它包含的数据多于输入列的错误吗?
- r - 如何导入 .R 文件并为其分配别名?就像 import myfile.R as mf