如何设置元素相对于另一个元素中选定文本的 xy 位置?

How to set elements xy-position relative to selected text in another element?

我正在尝试在文本区域中制作一个简单的工具提示元素。这个想法是,工具提示应该显示选择的内容。到目前为止我的代码是:

import React, { useRef, useState } from 'react';

const Contact = () => {
    const myref = useRef();
    const [tooltip, setTooltip] = useState('');

    const handleMouseUp = (e) => {
        if (window.getSelection().toString() !== '') {
            myref.current.style.display = "inline-block";
            myref.current.style.background = "black";
            myref.current.style.color = "white";
            setTooltip(window.getSelection().toString());

            myref.current.style.top = e.clientY + "px";
            myref.current.style.left = e.clientX + "px";
        }
    }

    return (
        <div className="contact">
            <h2>Contact</h2>

            <textarea
               rows="10" cols="100"
               onMouseUp={handleMouseUp}
               value="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sit amet vestibulum odio. Morbi porttitor, ante fermentum condimentum porta, elit tellus blandit lorem, eu porttitor turpis lectus sed urna. Morbi semper, velit luctus finibus aliquam, orci orci commodo velit, ut ultrices ligula ex id nulla. Quisque enim leo, mollis a consectetur quis, vestibulum id eros. Integer non vehicula ligula. Nulla eu quam consectetur, elementum felis rutrum, lobortis dolor. Mauris laoreet egestas orci, at posuere odio sagittis sagittis. Sed consequat urna turpis, ut tincidunt nunc posuere sit amet. In dui leo, euismod et tempus sed, sodales vitae nisi. Nam faucibus aliquet condimentum. Curabitur scelerisque, quam in dignissim mattis, erat felis ultrices metus, et sagittis purus magna quis magna."
            />

            <div ref={myref} style={{ display: 'none', position: 'absolute' }}>{tooltip}</div>

        </div >
    )
}

export default Contact;

但是我无法将工具提示位置设置在所选文本的正下方。有什么想法吗?

getBoundingClientRect 似乎可以解决问题。

import React, { useRef, useState } from 'react';

const Contact = () => {
    const myref = useRef();
    const myref2 = useRef();
    const [tooltip, setTooltip] = useState('');

    const handleMouseUp = (e) => {
        console.log(e.current);
        if (window.getSelection().toString() !== '') {
            myref.current.style.display = "inline-block";
            myref.current.style.background = "black";
            myref.current.style.color = "white";
            setTooltip(window.getSelection().toString());

            myref.current.style.left = (e.clientX - myref2.current.getBoundingClientRect().left) + "px";
            myref.current.style.top = (e.clientY - myref2.current.getBoundingClientRect().top) + "px";
        }
    }

    return (
        <div className="contact" ref={myref2}>
            <h2>Contact</h2>

            <textarea
                rows="10" cols="100"
                // onMouseUp={handleMouseUp}
                onChange={() => { }}
                onMouseUp={handleMouseUp}
                value="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sit amet vestibulum odio. Morbi porttitor, ante fermentum condimentum porta, elit tellus blandit lorem, eu porttitor turpis lectus sed urna. Morbi semper, velit luctus finibus aliquam, orci orci commodo velit, ut ultrices ligula ex id nulla. Quisque enim leo, mollis a consectetur quis, vestibulum id eros. Integer non vehicula ligula. Nulla eu quam consectetur, elementum felis rutrum, lobortis dolor. Mauris laoreet egestas orci, at posuere odio sagittis sagittis. Sed consequat urna turpis, ut tincidunt nunc posuere sit amet. In dui leo, euismod et tempus sed, sodales vitae nisi. Nam faucibus aliquet condimentum. Curabitur scelerisque, quam in dignissim mattis, erat felis ultrices metus, et sagittis purus magna quis magna."
            />

            <div ref={myref} style={{ display: 'none', position: 'absolute' }}>{tooltip}</div>

        </div >
    )
}

export default Contact;