import React, { useState, useRef, useEffect } from 'react'; import ReactQuill from 'react-quill'; import 'react-quill/dist/quill.snow.css'; import { Form } from 'antd'; import { EyeOutlined, CloseOutlined } from '@ant-design/icons'; // 提取纯文本工具函数 const extractPlainText = (html: string): string => { if (!html) return ''; const tempDiv = document.createElement('div'); tempDiv.innerHTML = html; return tempDiv.textContent || ''; }; interface LinkData { id: string; originalText: string; url: string; isDeleted: boolean; } const PersistentImagePreviewEditor = () => { const [form] = Form.useForm(); const [editorHtml, setEditorHtml] = useState(`

系统工作人员联系方式

系统工作人员联系方式表: 【示意图序号_a2966033634305507328_2】, 第二个标签 【示意图序号_a2966033634305507328_2】, 第三个标签 【示意图序号_a2966033634305507328_2】

`); const [plainText, setPlainText] = useState(extractPlainText(editorHtml)); const [linkDataList, setLinkDataList] = useState([]); const [activeImageUrl, setActiveImageUrl] = useState(null); // 跟踪鼠标是否在链接或预览区上 const [isHoveringLink, setIsHoveringLink] = useState(false); const [isHoveringPreview, setIsHoveringPreview] = useState(false); const editorContainerRef = useRef(null); const previewRef = useRef(null); // 初始化链接数据 useEffect(() => { const parser = new DOMParser(); const doc = parser.parseFromString(editorHtml, 'text/html'); const links = doc.getElementsByTagName('a'); const linksData: LinkData[] = []; Array.from(links).forEach((link, index) => { linksData.push({ id: `link-${index}-${Date.now()}`, originalText: link.textContent || '', url: link.href, isDeleted: false }); }); setLinkDataList(linksData); }, []); // 处理内容变化 const handleEditorChange = (html: string) => { setEditorHtml(html); const text = extractPlainText(html); setPlainText(text); form.setFieldsValue({ slice_text: text }); if (linkDataList.length > 0) { const updatedLinks = [...linkDataList]; updatedLinks.forEach(link => { const feature = link.originalText.slice(0, 5); link.isDeleted = !text.includes(feature); }); setLinkDataList(updatedLinks); } }; // 处理鼠标悬停链接事件 useEffect(() => { if (!editorContainerRef.current) return; const handleMouseOverLink = (e: MouseEvent) => { const target = e.target as HTMLAnchorElement; if (target.tagName === 'A') { const url = target.href; const isKnownLink = linkDataList.some(link => !link.isDeleted && url.includes(link.url) ); if (isKnownLink) { console.log('图片地址:', url); setActiveImageUrl(url); setIsHoveringLink(true); } } }; const handleMouseOutLink = () => { setIsHoveringLink(false); }; const container = editorContainerRef.current; container.addEventListener('mouseover', handleMouseOverLink); container.addEventListener('mouseout', handleMouseOutLink); return () => { container.removeEventListener('mouseover', handleMouseOverLink); container.removeEventListener('mouseout', handleMouseOutLink); }; }, [linkDataList]); // 控制预览区显示/隐藏的核心逻辑 useEffect(() => { // 当鼠标既不在链接上也不在预览区上时,才隐藏预览 if (!isHoveringLink && !isHoveringPreview) { setActiveImageUrl(null); } }, [isHoveringLink, isHoveringPreview]); // 配置编辑器(无工具栏) const modules = { toolbar: false }; return (
{/* 容器:编辑器 + 右侧图片预览区 */}
{/* 500x500的编辑器 */}
{/* 右侧图片预览区(固定位置) */} {activeImageUrl && (
setIsHoveringPreview(true)} onMouseOut={() => setIsHoveringPreview(false)} >
图片预览
setActiveImageUrl(null)} />
示意图预览 setActiveImageUrl(null)} />
)}
); }; export default PersistentImagePreviewEditor;