|
|
@@ -71,14 +71,12 @@ Page({
|
|
|
museumApi.getMuseumDetail(2)
|
|
|
.then(response => {
|
|
|
if (response) {
|
|
|
- // const parsedContent = this.parseContent(response.content || response.context);
|
|
|
let article = response.context;
|
|
|
- // console.log('解析后的内容:', parsedContent);
|
|
|
- WxParse.wxParse('article', 'html', article, that, 5);
|
|
|
this.setData({
|
|
|
detailData: response,
|
|
|
// contentItems: parsedContent
|
|
|
});
|
|
|
+ WxParse.wxParse('article', 'html', article, that, 5);
|
|
|
}
|
|
|
})
|
|
|
.catch(error => {
|
|
|
@@ -99,212 +97,6 @@ Page({
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
- * 处理HTML实体编码
|
|
|
- */
|
|
|
- processHtmlEntities(text) {
|
|
|
- if (!text) return '';
|
|
|
- return text
|
|
|
- .replace(/ /g, ' ')
|
|
|
- .replace(/ /g, ' ')
|
|
|
- .replace(/ /g, ' ')
|
|
|
- .replace(/ /g, ' ')
|
|
|
- .replace(/ /g, ' ');
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 解析style属性
|
|
|
- */
|
|
|
- parseStyleAttribute(styleStr) {
|
|
|
- const styles = {};
|
|
|
- if (styleStr) {
|
|
|
- styleStr.split(';').forEach(rule => {
|
|
|
- const [property, value] = rule.split(':').map(s => s.trim());
|
|
|
- if (property && value) {
|
|
|
- styles[property] = value;
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- return styles;
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 检查是否有删除线样式
|
|
|
- */
|
|
|
- hasStrikethrough(attributes) {
|
|
|
- // 检查style属性中的text-decoration
|
|
|
- const styleMatch = attributes.match(/style="([^"]*)"/i);
|
|
|
- if (styleMatch) {
|
|
|
- const styles = this.parseStyleAttribute(styleMatch[1]);
|
|
|
- return styles['text-decoration']?.includes('line-through') ||
|
|
|
- styles['text-decoration-line']?.includes('line-through');
|
|
|
- }
|
|
|
-
|
|
|
- // 检查class属性中是否包含删除线相关类名
|
|
|
- const classMatch = attributes.match(/class="([^"]*)"/i);
|
|
|
- if (classMatch) {
|
|
|
- const classes = classMatch[1].toLowerCase();
|
|
|
- return classes.includes('strikethrough') ||
|
|
|
- classes.includes('line-through') ||
|
|
|
- classes.includes('deleted');
|
|
|
- }
|
|
|
-
|
|
|
- return false;
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 解析HTML内容为不同类型的内容项
|
|
|
- */
|
|
|
- parseContent(content) {
|
|
|
- if (!content) return [];
|
|
|
-
|
|
|
- const contentItems = [];
|
|
|
- const matches = [];
|
|
|
-
|
|
|
- // 定义所有匹配规则
|
|
|
- const patterns = [
|
|
|
- { regex: /<h[1-6]([^>]*?)>(.*?)<\/h[1-6]>/gi, type: 'heading', handler: (match) => { let text = match[2].replace(/<[^>]*>/g, ''); let attributes = match[1]; let isCenter = /text-align\s*:\s*center/i.test(attributes) || /style="[^"]*text-align\s*:\s*center[^"]*"/i.test(attributes); return { type: 'heading', content: this.processHtmlEntities(text), center: isCenter }; } },
|
|
|
- {
|
|
|
- regex: /<span[^>]*>(.*?)<\/span>/gi,
|
|
|
- type: 'span',
|
|
|
- handler: (match) => {
|
|
|
- let text = match[1].replace(/<[^>]*>/g, '');
|
|
|
- return {
|
|
|
- type: 'span',
|
|
|
- content: this.processHtmlEntities(text)
|
|
|
- };
|
|
|
- }
|
|
|
- },
|
|
|
- // 检测删除线标签(del, s, strike)
|
|
|
- {
|
|
|
- regex: /<(del|s|strike)[^>]*>(.*?)<\/(del|s|strike)>/gi,
|
|
|
- type: 'strikethrough',
|
|
|
- handler: (match) => {
|
|
|
- let text = match[2].replace(/<[^>]*>/g, '');
|
|
|
- return {
|
|
|
- type: 'strikethrough',
|
|
|
- content: this.processHtmlEntities(text)
|
|
|
- };
|
|
|
- }
|
|
|
- },
|
|
|
- // 检测带有删除线样式的任意标签
|
|
|
- {
|
|
|
- regex: /<(\w+)([^>]*style="[^"]*text-decoration[^"]*line-through[^"]*"[^>]*)>(.*?)<\/\1>/gi,
|
|
|
- type: 'strikethrough',
|
|
|
- handler: (match) => {
|
|
|
- let text = match[3].replace(/<[^>]*>/g, '');
|
|
|
- return {
|
|
|
- type: 'strikethrough',
|
|
|
- content: this.processHtmlEntities(text)
|
|
|
- };
|
|
|
- }
|
|
|
- },
|
|
|
- // 检测带有删除线类名的任意标签
|
|
|
- {
|
|
|
- regex: /<(\w+)([^>]*class="[^"]*(?:strikethrough|line-through|deleted)[^"]*"[^>]*)>(.*?)<\/\1>/gi,
|
|
|
- type: 'strikethrough',
|
|
|
- handler: (match) => {
|
|
|
- let text = match[3].replace(/<[^>]*>/g, '');
|
|
|
- return {
|
|
|
- type: 'strikethrough',
|
|
|
- content: this.processHtmlEntities(text)
|
|
|
- };
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- regex: /<p[^>]*>(.*?)<\/p>/gi,
|
|
|
- type: 'text',
|
|
|
- handler: (match) => {
|
|
|
- let text = match[1].replace(/<[^>]*>/g, '');
|
|
|
- return {
|
|
|
- type: 'text',
|
|
|
- content: this.processHtmlEntities(text)
|
|
|
- };
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- regex: /<div[^>]*class="[^"]*media-wrap[^"]*image-wrap[^"]*"[^>]*>.*?<img[^>]*src="([^"]+)"[^>]*(?:alt="([^"]*)")?\/?>.* ?<\/div>/gi,
|
|
|
- type: 'image',
|
|
|
- handler: (match) => ({
|
|
|
- type: 'image',
|
|
|
- src: match[1],
|
|
|
- alt: match[2] || '图片'
|
|
|
- })
|
|
|
- },
|
|
|
- {
|
|
|
- regex: /<div[^>]*class="[^"]*media-wrap[^"]*video-wrap[^"]*"[^>]*>.*?<video[^>]*src="([^"]+)"[^>]*(?:poster="([^"]*)")?\/?>.* ?<\/div>/gi,
|
|
|
- type: 'video',
|
|
|
- handler: (match) => ({
|
|
|
- type: 'video',
|
|
|
- src: match[1],
|
|
|
- poster: match[2] || ''
|
|
|
- })
|
|
|
- },
|
|
|
- {
|
|
|
- regex: /<div[^>]*class="[^"]*media-wrap[^"]*audio-wrap[^"]*"[^>]*>.*?<audio[^>]*src="([^"]+)"[^>]*(?:title="([^"]*)")?\/?>.* ?<\/div>/gi,
|
|
|
- type: 'audio',
|
|
|
- handler: (match) => ({
|
|
|
- type: 'audio',
|
|
|
- src: match[1],
|
|
|
- title: match[2] || '音频'
|
|
|
- })
|
|
|
- }
|
|
|
- ];
|
|
|
-
|
|
|
- // 收集所有匹配项及其位置
|
|
|
- patterns.forEach(pattern => {
|
|
|
- let match;
|
|
|
- pattern.regex.lastIndex = 0; // 重置正则表达式的lastIndex
|
|
|
- while ((match = pattern.regex.exec(content)) !== null) {
|
|
|
- const item = pattern.handler(match);
|
|
|
- if ((item.type === 'text' && item.content.trim()) || item.type !== 'text') {
|
|
|
- matches.push({
|
|
|
- index: match.index,
|
|
|
- length: match[0].length,
|
|
|
- item: item
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- // 按照在原HTML中的位置排序
|
|
|
- matches.sort((a, b) => a.index - b.index);
|
|
|
-
|
|
|
- // 移除重叠的匹配项(保持原始顺序,只过滤真正重复的内容)
|
|
|
- const filteredMatches = [];
|
|
|
- const typesPriority = ['heading', 'strikethrough', 'span', 'text']; // 优先级从高到低
|
|
|
-
|
|
|
- for (let i = 0; i < matches.length; i++) {
|
|
|
- const current = matches[i];
|
|
|
- let shouldSkip = false;
|
|
|
-
|
|
|
- // 检查是否与已添加的项有重叠
|
|
|
- for (let j = 0; j < filteredMatches.length; j++) {
|
|
|
- const existing = filteredMatches[j];
|
|
|
- // 检查是否有重叠
|
|
|
- if (current.index < existing.index + existing.length &&
|
|
|
- current.index + current.length > existing.index) {
|
|
|
- // 如果有重叠,比较优先级
|
|
|
- const currentPriority = typesPriority.indexOf(current.item.type);
|
|
|
- const existingPriority = typesPriority.indexOf(existing.item.type);
|
|
|
-
|
|
|
- // 只有当前项优先级明显低于已存在项时才跳过
|
|
|
- if (currentPriority > existingPriority && existingPriority !== -1) {
|
|
|
- shouldSkip = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!shouldSkip) {
|
|
|
- filteredMatches.push(current);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 提取排序后的内容项
|
|
|
- return filteredMatches.map(match => match.item);
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
* 生命周期函数--监听页面初次渲染完成
|
|
|
*/
|
|
|
onReady() {
|