|
|
|
@ -57,6 +57,7 @@ |
|
|
|
'lead-text': isCardTextHighlighted(page, itemIndex), |
|
|
|
'introduction-text' : item.isLead, |
|
|
|
}" |
|
|
|
:id="`text-${itemIndex}`" |
|
|
|
v-else-if="item && item.type === 'text' && item.content" |
|
|
|
@click.stop="handleTextClick(item.content, item, index)"> |
|
|
|
<text v-for="(segment, segmentIndex) in processChineseText(item.content)" |
|
|
|
@ -211,6 +212,8 @@ export default { |
|
|
|
pageWords: [], |
|
|
|
// 存储每个页面的付费状态 |
|
|
|
pagePay: [], |
|
|
|
|
|
|
|
elementPositionsCache: {}, // 缓存每个页面的元素位置信息 |
|
|
|
} |
|
|
|
}, |
|
|
|
onShow() { |
|
|
|
@ -519,19 +522,6 @@ export default { |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
// 处理音频切换时的自动滚动 |
|
|
|
// onScrollToText(refName) { |
|
|
|
// try { |
|
|
|
// console.log('🎯 onScrollToText 被调用:', refName); |
|
|
|
// |
|
|
|
// // 调用scrollTo插件 |
|
|
|
// this.$scrollTo(refName); |
|
|
|
// |
|
|
|
// } catch (error) { |
|
|
|
// console.error('❌ onScrollToText 执行失败:', error); |
|
|
|
// } |
|
|
|
// }, |
|
|
|
|
|
|
|
// 处理文本点击事件 |
|
|
|
handleTextClick(textContent, item, pageIndex) { |
|
|
|
|
|
|
|
@ -724,7 +714,7 @@ export default { |
|
|
|
|
|
|
|
// 检查是否应该阻止自动滚动(用户正在手动操作) |
|
|
|
if (this.shouldPreventAutoScroll()) { |
|
|
|
console.log('🚫 用户正在手动滚动,跳过自动滚动到文本'); |
|
|
|
// console.log('🚫 用户正在手动滚动,跳过自动滚动到文本'); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
@ -736,7 +726,7 @@ export default { |
|
|
|
this.scrollDebounceTimer = setTimeout(() => { |
|
|
|
// 再次检查是否应该阻止自动滚动 |
|
|
|
if (this.shouldPreventAutoScroll()) { |
|
|
|
console.log('🚫 防抖延迟后检测到用户手动滚动,跳过自动滚动到文本'); |
|
|
|
// console.log('🚫 防抖延迟后检测到用户手动滚动,跳过自动滚动到文本'); |
|
|
|
return; |
|
|
|
} |
|
|
|
this.performScrollToText(scrollData); |
|
|
|
@ -747,7 +737,7 @@ export default { |
|
|
|
performScrollToText(scrollData) { |
|
|
|
// 最终检查:如果用户正在手动操作,直接返回 |
|
|
|
if (this.shouldPreventAutoScroll()) { |
|
|
|
console.log('🚫 执行滚动前检测到用户手动操作,取消自动滚动'); |
|
|
|
// console.log('🚫 执行滚动前检测到用户手动操作,取消自动滚动'); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
@ -845,13 +835,13 @@ export default { |
|
|
|
} |
|
|
|
} else { |
|
|
|
// 精确计算失败,使用原有的查询方法作为备用 |
|
|
|
console.log('🔄 精确计算失败,使用备用查询方法'); |
|
|
|
this.fallbackScrollToText(selector, resetScrollingState, safetyTimeout); |
|
|
|
console.error('🔄 精确计算失败,使用备用查询方法'); |
|
|
|
//this.fallbackScrollToText(selector, resetScrollingState, safetyTimeout); |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
console.error('❌ 精确滚动计算失败:', error); |
|
|
|
// 使用原有的查询方法作为备用 |
|
|
|
this.fallbackScrollToText(selector, resetScrollingState, safetyTimeout); |
|
|
|
//this.fallbackScrollToText(selector, resetScrollingState, safetyTimeout); |
|
|
|
} |
|
|
|
}); |
|
|
|
}, |
|
|
|
@ -966,6 +956,13 @@ export default { |
|
|
|
// 获取所有页面元素的位置信息 |
|
|
|
async getAllElementPositions() { |
|
|
|
return new Promise((resolve) => { |
|
|
|
|
|
|
|
// 检查缓存是否存在 |
|
|
|
if (this.elementPositionsCache[this.currentPage - 1]) { |
|
|
|
resolve(this.elementPositionsCache[this.currentPage - 1]); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
const currentPageData = this.bookPages[this.currentPage - 1]; |
|
|
|
if (!currentPageData || !Array.isArray(currentPageData)) { |
|
|
|
resolve([]); |
|
|
|
@ -993,6 +990,7 @@ export default { |
|
|
|
|
|
|
|
query.exec((res) => { |
|
|
|
const containerRect = res[0]; |
|
|
|
console.log('getAllElementPositions res:', res, this.scrollTops[this.currentPage - 1]); |
|
|
|
if (!containerRect) { |
|
|
|
resolve([]); |
|
|
|
return; |
|
|
|
@ -1004,12 +1002,14 @@ export default { |
|
|
|
if (item && (item.type === 'text' || item.type === 'image' || item.type === 'video')) { |
|
|
|
const elementRect = res[resultIndex]; |
|
|
|
if (elementRect) { |
|
|
|
let top = elementRect.top - (containerRect.height / 2); |
|
|
|
elementPositions.push({ |
|
|
|
id : elementRect.id, |
|
|
|
index: index, |
|
|
|
type: item.type, |
|
|
|
top: elementRect.top - containerRect.top, |
|
|
|
top: top, |
|
|
|
height: elementRect.height, |
|
|
|
bottom: elementRect.top - containerRect.top + elementRect.height |
|
|
|
bottom: top + elementRect.height |
|
|
|
}); |
|
|
|
} |
|
|
|
resultIndex++; |
|
|
|
@ -1018,6 +1018,12 @@ export default { |
|
|
|
|
|
|
|
resolve(elementPositions); |
|
|
|
}); |
|
|
|
}).then((elementPositions) => { |
|
|
|
//进行缓存 |
|
|
|
if (elementPositions.length > 0) { |
|
|
|
this.elementPositionsCache[this.currentPage - 1] = elementPositions; |
|
|
|
} |
|
|
|
return elementPositions; |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
@ -1098,10 +1104,10 @@ export default { |
|
|
|
|
|
|
|
let targetElementIndex = -1; |
|
|
|
|
|
|
|
if (scrollData.segmentIndex !== undefined) { |
|
|
|
// 分段音频情况 |
|
|
|
targetElementIndex = scrollData.segmentIndex; |
|
|
|
} else if (scrollData.highlightIndex !== undefined) { |
|
|
|
// if (scrollData.segmentIndex !== undefined) { |
|
|
|
// // 分段音频情况 |
|
|
|
// targetElementIndex = scrollData.segmentIndex; |
|
|
|
if (scrollData.highlightIndex !== undefined) { |
|
|
|
// 普通音频情况,需要找到对应的文本元素 |
|
|
|
targetElementIndex = this.findTextItemIndex(scrollData.highlightIndex); |
|
|
|
} |
|
|
|
@ -1114,7 +1120,7 @@ export default { |
|
|
|
const targetElement = elementPositions.find(pos => pos.index === targetElementIndex && pos.type === 'text'); |
|
|
|
|
|
|
|
if (!targetElement) { |
|
|
|
console.warn('未找到目标元素位置信息:', targetElementIndex); |
|
|
|
console.error('未找到目标元素位置信息:', elementPositions, targetElementIndex); |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1859,6 +1865,7 @@ export default { |
|
|
|
console.error('课程切换后音频加载失败:', error); |
|
|
|
} |
|
|
|
} |
|
|
|
this.getAllElementPositions() |
|
|
|
}); |
|
|
|
|
|
|
|
// 预加载后续几页的内容(异步执行,不阻塞当前页面显示) |
|
|
|
|