|
|
@@ -1,20 +1,27 @@
|
|
|
/* eslint-disable jsx-a11y/anchor-is-valid */
|
|
|
import React, { useState, useEffect, useRef } from 'react'
|
|
|
import styles from './index.module.scss'
|
|
|
-import { myData } from '@/utils/http'
|
|
|
+import { isPc, myData } from '@/utils/http'
|
|
|
import { Tooltip } from 'antd'
|
|
|
import { callIframeFu, isMobiileFu } from '@/utils/history'
|
|
|
+import classNames from 'classnames'
|
|
|
|
|
|
-function ModalTxt({ setIsShowTabBar, setIsShowMzmTitle }: { setIsShowTabBar: (isShowTabBar: boolean) => void; setIsShowMzmTitle: (isShowMzmTitle: boolean) => void }) {
|
|
|
+function ModalTxt({
|
|
|
+ setIsShowTabBar,
|
|
|
+ setIsShowMzmTitle
|
|
|
+}: {
|
|
|
+ setIsShowTabBar: (isShowTabBar: boolean) => void
|
|
|
+ setIsShowMzmTitle: (isShowMzmTitle: boolean) => void
|
|
|
+}) {
|
|
|
const [selectedTab, setSelectedTab] = useState(0)
|
|
|
|
|
|
const [activeAId, setActiveAId] = useState<number | null>(null)
|
|
|
const [showTooltip, setShowTooltip] = useState(-1)
|
|
|
|
|
|
- const ori_touchStartX = useRef(0);
|
|
|
- const trans_touchStartX = useRef(0);
|
|
|
- const originRef = useRef<any>(null);
|
|
|
- const translateRef = useRef<any>(null);
|
|
|
+ const ori_touchStartX = useRef(0)
|
|
|
+ const trans_touchStartX = useRef(0)
|
|
|
+ const originRef = useRef<any>(null)
|
|
|
+ const translateRef = useRef<any>(null)
|
|
|
|
|
|
useEffect(() => {
|
|
|
if (selectedTab !== 0) {
|
|
|
@@ -23,7 +30,6 @@ function ModalTxt({ setIsShowTabBar, setIsShowMzmTitle }: { setIsShowTabBar: (is
|
|
|
}
|
|
|
}, [selectedTab, setIsShowMzmTitle, setIsShowTabBar])
|
|
|
|
|
|
-
|
|
|
useEffect(() => {
|
|
|
localStorage.setItem('selectedBeiwen', selectedTab.toString())
|
|
|
}, [selectedTab])
|
|
|
@@ -32,28 +38,38 @@ function ModalTxt({ setIsShowTabBar, setIsShowMzmTitle }: { setIsShowTabBar: (is
|
|
|
|
|
|
// 处理触摸移动事件
|
|
|
const handleOriTouchMove = (e: any) => {
|
|
|
- e.preventDefault();
|
|
|
- const deltaX = e.touches[0].clientX - ori_touchStartX.current;
|
|
|
+ e.preventDefault()
|
|
|
+ const deltaX = e.touches[0].clientX - ori_touchStartX.current
|
|
|
if (originRef.current) {
|
|
|
- originRef.current.scrollTop += deltaX;
|
|
|
+ originRef.current.scrollTop += deltaX
|
|
|
}
|
|
|
- ori_touchStartX.current = e.touches[0].clientX;
|
|
|
- };
|
|
|
+ ori_touchStartX.current = e.touches[0].clientX
|
|
|
+ }
|
|
|
const handleTransTouchMove = (e: any) => {
|
|
|
- e.preventDefault();
|
|
|
- const deltaX = e.touches[0].clientX - trans_touchStartX.current;
|
|
|
+ e.preventDefault()
|
|
|
+ const deltaX = e.touches[0].clientX - trans_touchStartX.current
|
|
|
if (translateRef.current) {
|
|
|
- translateRef.current.scrollTop += deltaX;
|
|
|
+ translateRef.current.scrollTop += deltaX
|
|
|
}
|
|
|
- trans_touchStartX.current = e.touches[0].clientX;
|
|
|
- };
|
|
|
+ trans_touchStartX.current = e.touches[0].clientX
|
|
|
+ }
|
|
|
// 处理触摸开始事件
|
|
|
const handleTouchStart = (e: any, start: any) => {
|
|
|
- start.current = e.touches[0].clientX;
|
|
|
- };
|
|
|
+ start.current = e.touches[0].clientX
|
|
|
+ }
|
|
|
|
|
|
//动态加入a标签
|
|
|
- const CommentLink = ({ index, word, define, inset }: { index: number; word: string; define: string; inset: string }) => {
|
|
|
+ const CommentLink = ({
|
|
|
+ index,
|
|
|
+ word,
|
|
|
+ define,
|
|
|
+ inset
|
|
|
+ }: {
|
|
|
+ index: number
|
|
|
+ word: string
|
|
|
+ define: string
|
|
|
+ inset: string
|
|
|
+ }) => {
|
|
|
const handleClick = () => {
|
|
|
setActiveAId(index)
|
|
|
setShowTooltip(index)
|
|
|
@@ -66,11 +82,15 @@ function ModalTxt({ setIsShowTabBar, setIsShowMzmTitle }: { setIsShowTabBar: (is
|
|
|
<div className='tooltip_MT'>
|
|
|
<div className='top'>
|
|
|
<div className='title'>{word}</div>
|
|
|
- <div className='close' onClick={() => setShowTooltip(-1)} onTouchEnd={() => setShowTooltip(-1)}>
|
|
|
+ <div
|
|
|
+ className='close'
|
|
|
+ onClick={() => setShowTooltip(-1)}
|
|
|
+ onTouchEnd={() => setShowTooltip(-1)}
|
|
|
+ >
|
|
|
<img src={require('@/assets/img/close.png')} alt='' draggable='false' />
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div className="content">{define}</div>
|
|
|
+ <div className='content'>{define}</div>
|
|
|
</div>
|
|
|
}
|
|
|
getPopupContainer={() => document.body.querySelector('#root') as HTMLElement}
|
|
|
@@ -80,7 +100,12 @@ function ModalTxt({ setIsShowTabBar, setIsShowMzmTitle }: { setIsShowTabBar: (is
|
|
|
align={{ offset: [-45, 0] }}
|
|
|
arrow={false}
|
|
|
>
|
|
|
- <a key={index} className={activeAId === index ? 'active' : ''} onTouchEnd={handleClick} onClick={handleClick} >
|
|
|
+ <a
|
|
|
+ key={index}
|
|
|
+ className={activeAId === index ? 'active' : ''}
|
|
|
+ onTouchEnd={handleClick}
|
|
|
+ onClick={handleClick}
|
|
|
+ >
|
|
|
{word}
|
|
|
</a>
|
|
|
</Tooltip>
|
|
|
@@ -88,32 +113,32 @@ function ModalTxt({ setIsShowTabBar, setIsShowMzmTitle }: { setIsShowTabBar: (is
|
|
|
}
|
|
|
|
|
|
const CommentText = ({ str, index }: { str: string; index: number }) => {
|
|
|
- const convertArr = myData.readDetail[index].words.map(item => item.name);
|
|
|
- const defineArr = myData.readDetail[index].words.map(item => item.define);
|
|
|
- const insetArr = myData.readDetail[index].words.map(item => item.inset);
|
|
|
- const parts: React.ReactNode[] = [];
|
|
|
- let remainingStr = str;
|
|
|
+ const convertArr = myData.readDetail[index].words.map(item => item.name)
|
|
|
+ const defineArr = myData.readDetail[index].words.map(item => item.define)
|
|
|
+ const insetArr = myData.readDetail[index].words.map(item => item.inset)
|
|
|
+ const parts: React.ReactNode[] = []
|
|
|
+ let remainingStr = str
|
|
|
|
|
|
// 工具函数:过滤 <p> 标签(保留文本,移除所有 <p> 和 </p>)
|
|
|
const removePTags = (text: string) => {
|
|
|
// 匹配所有 <p...> 和 </p> 标签,替换为空(保留内部文本)
|
|
|
- return text.replace(/<p[^>]*>/gi, '').replace(/<\/p>/gi, '');
|
|
|
- };
|
|
|
+ return text.replace(/<p[^>]*>/gi, '').replace(/<\/p>/gi, '')
|
|
|
+ }
|
|
|
|
|
|
// 先过滤原始字符串中的 <p> 标签
|
|
|
- remainingStr = removePTags(remainingStr);
|
|
|
+ remainingStr = removePTags(remainingStr)
|
|
|
// 若 word/define 也带 <p>,同步过滤(按需开启)
|
|
|
// convertArr = convertArr.map(word => removePTags(word));
|
|
|
// defineArr = defineArr.map(define => removePTags(define));
|
|
|
|
|
|
convertArr.forEach((word, idx) => {
|
|
|
// 注意:若 word 含特殊字符(如 . * +),需转义正则
|
|
|
- const escapedWord = word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
|
- const regex = new RegExp(escapedWord);
|
|
|
- const match = remainingStr.match(regex);
|
|
|
+ const escapedWord = word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
|
+ const regex = new RegExp(escapedWord)
|
|
|
+ const match = remainingStr.match(regex)
|
|
|
|
|
|
if (match) {
|
|
|
- const matchIndex = match.index || 0;
|
|
|
+ const matchIndex = match.index || 0
|
|
|
|
|
|
// 添加匹配前的文本(已过滤 <p>)
|
|
|
if (matchIndex > 0) {
|
|
|
@@ -122,7 +147,7 @@ function ModalTxt({ setIsShowTabBar, setIsShowMzmTitle }: { setIsShowTabBar: (is
|
|
|
key={`text-before-${idx}`}
|
|
|
dangerouslySetInnerHTML={{ __html: remainingStr.substring(0, matchIndex) }}
|
|
|
/>
|
|
|
- );
|
|
|
+ )
|
|
|
}
|
|
|
|
|
|
// 添加链接组件(若 define 带 <p>,这里也可过滤:define={removePTags(defineArr[idx])})
|
|
|
@@ -134,25 +159,20 @@ function ModalTxt({ setIsShowTabBar, setIsShowMzmTitle }: { setIsShowTabBar: (is
|
|
|
define={defineArr[idx]}
|
|
|
inset={insetArr[idx]}
|
|
|
/>
|
|
|
- );
|
|
|
+ )
|
|
|
|
|
|
// 更新剩余字符串
|
|
|
- remainingStr = remainingStr.substring(matchIndex + word.length);
|
|
|
+ remainingStr = remainingStr.substring(matchIndex + word.length)
|
|
|
}
|
|
|
- });
|
|
|
+ })
|
|
|
|
|
|
// 添加剩余文本(已过滤 <p>)
|
|
|
if (remainingStr) {
|
|
|
- parts.push(
|
|
|
- <span
|
|
|
- key="text-remaining"
|
|
|
- dangerouslySetInnerHTML={{ __html: remainingStr }}
|
|
|
- />
|
|
|
- );
|
|
|
+ parts.push(<span key='text-remaining' dangerouslySetInnerHTML={{ __html: remainingStr }} />)
|
|
|
}
|
|
|
|
|
|
- return <>{parts}</>;
|
|
|
- };
|
|
|
+ return <>{parts}</>
|
|
|
+ }
|
|
|
|
|
|
const handleBeie = () => {
|
|
|
window.location.replace('#/beie')
|
|
|
@@ -165,10 +185,8 @@ function ModalTxt({ setIsShowTabBar, setIsShowMzmTitle }: { setIsShowTabBar: (is
|
|
|
}
|
|
|
|
|
|
return (
|
|
|
- <div className={styles.modalTxt} id='modalTxt'>
|
|
|
+ <div className={classNames(styles.modalTxt, isPc ? '' : styles.modalTxtMo)} id='modalTxt'>
|
|
|
<div className='modalTxtContainner'>
|
|
|
-
|
|
|
-
|
|
|
<div className='topBar'>
|
|
|
<div className='beie'>
|
|
|
<img src={require('@/assets/img/beie.png')} alt='' />
|
|
|
@@ -225,7 +243,12 @@ function ModalTxt({ setIsShowTabBar, setIsShowMzmTitle }: { setIsShowTabBar: (is
|
|
|
<div className='detailTxt'>
|
|
|
<div className='left'>
|
|
|
<div className='title'>原文</div>
|
|
|
- <div className='txt' onTouchMove={handleOriTouchMove} onTouchStart={(e) => handleTouchStart(e, ori_touchStartX)} ref={originRef}>
|
|
|
+ <div
|
|
|
+ className='txt'
|
|
|
+ onTouchMove={handleOriTouchMove}
|
|
|
+ onTouchStart={e => handleTouchStart(e, ori_touchStartX)}
|
|
|
+ ref={originRef}
|
|
|
+ >
|
|
|
{CommentText({
|
|
|
str: myData.readDetail[selectedTab - 1].origin,
|
|
|
index: selectedTab - 1
|
|
|
@@ -234,7 +257,13 @@ function ModalTxt({ setIsShowTabBar, setIsShowMzmTitle }: { setIsShowTabBar: (is
|
|
|
</div>
|
|
|
<div className='right'>
|
|
|
<div className='title'>译文</div>
|
|
|
- <div className='txt' onTouchMove={handleTransTouchMove} onTouchStart={(e) => handleTouchStart(e, trans_touchStartX)} ref={translateRef} dangerouslySetInnerHTML={{ __html: myData.readDetail[selectedTab - 1].translate }}></div>
|
|
|
+ <div
|
|
|
+ className='txt'
|
|
|
+ onTouchMove={handleTransTouchMove}
|
|
|
+ onTouchStart={e => handleTouchStart(e, trans_touchStartX)}
|
|
|
+ ref={translateRef}
|
|
|
+ dangerouslySetInnerHTML={{ __html: myData.readDetail[selectedTab - 1].translate }}
|
|
|
+ ></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
)}
|
|
|
@@ -243,7 +272,8 @@ function ModalTxt({ setIsShowTabBar, setIsShowMzmTitle }: { setIsShowTabBar: (is
|
|
|
<div className='content'>
|
|
|
<div className='title'>碑文概述</div>
|
|
|
<div className='text'>
|
|
|
- <p>碑额留出高约15厘米的空白范围,仅在碑额左侧题写造碑日期。《山
|
|
|
+ <p>
|
|
|
+ 碑额留出高约15厘米的空白范围,仅在碑额左侧题写造碑日期。《山
|
|
|
西通志》指出:其“碑额题‘大魏天平元年岁次甲寅十一月庚辰朔三日壬午造讫’
|
|
|
岁月书额,唐贞观晋祠铭以前,此为仅见”。
|
|
|
</p>
|
|
|
@@ -251,7 +281,6 @@ function ModalTxt({ setIsShowTabBar, setIsShowMzmTitle }: { setIsShowTabBar: (is
|
|
|
程哲碑碑文,31行楷书,满行45字,字径约2厘米,带方界格,总计
|
|
|
1404字;未刻正式碑名。通篇颂德程氏家族的历史功绩。
|
|
|
</p>
|
|
|
-
|
|
|
</div>
|
|
|
</div>
|
|
|
)}
|