首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在没有库的情况下创建带有焦点陷阱的对话框

如何在没有库的情况下创建带有焦点陷阱的对话框
EN

Stack Overflow用户
提问于 2022-01-07 18:39:15
回答 1查看 460关注 0票数 1

到目前为止,我看到的代码示例使用的是库,比如JQuery和react焦点锁定https://www.npmjs.com/package/react-focus-lock,我非常喜欢一个简单的例子,在一个模式中有两个按钮,这样就不能通过选项卡将模式之外的元素对焦。

EN

回答 1

Stack Overflow用户

发布于 2022-10-25 19:00:01

我使用下面的组件来包装必须捕获焦点的内容:

代码语言:javascript
运行
复制
import { useRef, useEffect } from "react";

type Props = {
    children: Array<JSX.Element | null>;
};

export const FocusTrap = (props: Props) => {
    const ref = useRef<HTMLSpanElement>(null);

    useEffect(() => {
        let firstElement: (HTMLElement | undefined);
        let lastElement: (HTMLElement | undefined);
        if (ref.current != null)
            for (const element of ref.current.querySelectorAll<HTMLElement>("[tabindex]"))
                considerElement(element);
        firstElement?.addEventListener("keydown", handleKeyOnFirst);
        lastElement?.addEventListener("keydown", handleKeyOnLast);
        return () => {
            firstElement?.removeEventListener("keydown", handleKeyOnFirst);
            lastElement?.removeEventListener("keydown", handleKeyOnLast);
        };

        function considerElement(element: HTMLElement) {
            // @ts-ignore
            if (!element.checkVisibility()) return;
            if (firstElement === undefined) firstElement = element;
            else lastElement = element;
        }

        function handleKeyOnFirst(event: KeyboardEvent) {
            if (event.key !== "Tab" || !event.shiftKey) return;
            event.preventDefault();
            lastElement?.focus();
        }

        function handleKeyOnLast(event: KeyboardEvent) {
            if (event.key !== "Tab" || event.shiftKey) return;
            event.preventDefault();
            firstElement?.focus();
        }
    }, [props.children]);

    return <span ref={ref}>{props.children}</span>;
};

像这样使用:

代码语言:javascript
运行
复制
<FocusTrap>
    <ModalOrOtherContentToTrapFocus/>
</FocusTrap>

陷阱组件扫描底层内容,找到第一个和最后一个具有tabIndex属性的可见元素,并为它们重写Tab/Shift+Tab行为。

请注意,在编写element.checkVisibility()函数时,它只是可在Chrome上使用函数。相关线程在SO:检查元素在DOM中是否可见上。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70625755

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档