首页 > 解决方案 > 如何使用popper.js将自定义反应元素悬停在触发器el之外或滚动后保持它在Yaxis上的位置

问题描述

我正在尝试利用 popper.js 在悬停元素的右侧放置一个组件。基本上我想要做的是,当我将鼠标悬停在标题中的图标上时,我希望在悬停图标的右侧出现一个完全不同的 div 中的 FeedbackCard 组件。据我了解,参考元素和 popper 元素都必须在同一个文件中,但是无论我是否滚动,如何强制 popper 元素跳出参考元素并将其自身定位在 X 轴上的同一水平面上上或下?

这是我的组件代码

import React, { useState } from "react";
import { SentryIcon } from "./SentryIcon";
import { usePopper } from "react-popper";
import { FeedbackCard } from "./FeedbackCard";
import { createPortal } from "react-dom";

//Vaviarnts are e.g. h1 h2 h3
export function Heading({
    children,
    bsClasses,
    info,
    variant,
    required,
    description
}) {
    const [show, setShow] = useState(false);
    const [referenceElement, setReferenceElement] = useState(null);
    const [popperElement, setPopperElement] = useState(null);
    const { styles, attributes } = usePopper(referenceElement, popperElement, {
        modifiers: [
            {
                name: "offset",
                options: {
                    offset: [10, 720]
                }
            },
            {
                name: "preventOverflow",
                options: {
                    mainAxis: false,
                    altAxis: false,

                    padding: 50
                }
            }
        ],
        placement: "right-end"
    });

    const DynamicHeading = `${variant}`;
    return (
        <div className="d-flex align-items-center">
            <div className="d-flex flex-column">
                <div className="d-flex">
                    <DynamicHeading className={`${bsClasses}`}>
                        {children}
                    </DynamicHeading>
                    {required && (
                        <span
                            style={{ fontSize: "1.5rem" }}
                            className={`text-danger ${variant} mx-1 center`}
                        >
                            *
                        </span>
                    )}
                    {info && (
                        <span
                            ref={setReferenceElement}
                            onMouseEnter={() => setShow(true)}
                            onMouseLeave={() => setShow(false)}
                        >
                            <SentryIcon
                                id={children}
                                icon="fas fa-info-circle"
                            />
                        </span>
                    )}
                </div>
                {description && (
                    <p className="small text-muted minus-mt-small">
                        {description}
                    </p>
                )}
            </div>
            {show && (
                <FeedbackCard
                    ref={setPopperElement}
                    style={styles.popper}
                    {...attributes.popper}
                    title={children}
                />
            )}
        </div>
    );
}

以前,我通过将 getBoundingClientRect() 值传递给卡片并设置其顶部值来定位反馈卡片组件,但是每当我滚动卡片的位置变化时。这整个东西放在4200px window.scrollHeight中间的某个地方,也许你知道一些计算可以减去相对于页面Y轴上最后一个位置的滚动量,可以与getBoundingClientRects().top一起使用保持元素始终在同一个 Ylevel 上?

非常感谢。

标签: javascriptcssreactjsdompopper.js

解决方案


推荐阅读