【问题标题】:JavaScript Node.contains() function does not check inner children elementsJavaScript Node.contains() 函数不检查内部子元素
【发布时间】:2021-06-09 10:59:10
【问题描述】:

我正在制作一个 React 应用程序,其中我制作了一个自定义 DatePicker 组件。如果发生外部点击,我希望它被隐藏(就像我对其他组件所做的那样,例如 Select Dropdown)。长话短说,我写了一个自定义钩子:

export default (ref, visible, setVisible) => {
    React.useEffect(() => {
        let handleClick;

        if (visible) {
            handleClick = (e) => {
                if (ref.current && !ref.current.contains(e.target)) {
                    setVisible((prevVisible) => !prevVisible);
                }
            };

            document.addEventListener('click', handleClick);
        }

        return () => {
            document.removeEventListener('click', handleClick);
        };
    }, [visible]);
};

问题是当我将它与 Select 组件一起使用时,该组件将其项目作为直接子项,一切正常,但使用 DatePicker,它在选择日期后关闭。这是因为 day 元素本身是我的日历容器的 REF 的内部子元素。结构是这样的:

<div class="picker">
    * A <p> tag here for triggering the visibility state *
    <div className="calendar" ref={calendar}>
        <div className="month">
            <div className="week">
                <div className="day">
                    * day number *
                </div>
                * More days *
            </div>
            * More weeks *
        </div>
        * Second month *
    </div>
</div>

在 MDN 文档中,我读到 ref.current.contains 应该遍历所有子元素,但它以某种方式仅检查具有“MONTH”类的 div,即仅直接子元素。有没有人遇到过同样的问题?我将不胜感激任何帮助!谢谢!

P.S 这是打开 DatePicker 组件后我的 DOM 树的图像:

【问题讨论】:

  • 引用传递给什么元素?
  • @evolutionxbox 包含两个月块内的日历元素(因为我制作了日期范围选择器)和控制按钮(上面的示例中没有)。附言检查上面的伪 jsx/html 标记代码示例,将 ref 属性传递给带有日历类名的 div
  • .calendar 中单击的任何元素都将导致ref.current.contains(e.target) 成为true
  • @evolutionxbox 突然之间,情况并非如此。不知何故,当我点击.month(因为我有填充)或.weekconsole.log(ref.current.contains(e.target))返回true,但是当我点击.day时,它们被放置在.week容器内,我不知何故在同一 console.log(ref.current.contains(e.target)) 上获取 false
  • 那么.week不是.calendar的后代?

标签: javascript html reactjs


【解决方案1】:

答案尽可能简单:我正在使用 Math.random() 为每个数组元素生成 key prop,不要这样做:)

用简单的数组索引替换它修复了这个错误。

附:不知何故,为了不使用数组索引而动态生成键,阻止了获取数组元素的 parentNode 属性的过程。它返回 null,尽管元素在 #document 根之前有 15 个父节点

【讨论】:

    猜你喜欢
    • 2018-01-11
    • 2023-03-12
    • 2023-03-09
    • 2016-08-01
    • 2014-10-20
    • 2016-11-09
    • 2020-02-21
    • 2011-01-10
    • 1970-01-01
    相关资源
    最近更新 更多