fix: 翻译完成后「查看之前的写作建议」意外收起

- 根因: 翻译完成 → renderOriginalPane 重建左栏 DOM,<details> 被重新创建,
  open 状态丢失(用户实测)
- 记录折叠区展开状态 priorGuidanceOpen,重建后按状态恢复;toggle 事件同步更新
- 顺带: 重建前记录/恢复内容区滚动位置,操作后内容不再跳回顶部
- 验证: 翻译完成 / 收起译文(缓存切换)/ 切段往返 均保持展开与缓存状态(5/5),无 JS 报错
This commit is contained in:
LuminousRuoxi
2026-09-10 16:34:37 +08:00
parent a81b366d71
commit 6189ee87d8
+12 -1
View File
@@ -272,6 +272,9 @@ let origTranslations = [];
let origTranslateOpen = []; let origTranslateOpen = [];
let analysisVersion = 1; let analysisVersion = 1;
let helpState = {}; let helpState = {};
// 「查看之前的写作建议」(<details>) 展开状态:翻译/切换等会重建左栏 DOM,
// 不记住的话翻译完成后会意外收起(用户实测)。
let priorGuidanceOpen = false;
let dirtyDuringRecheck = false; let dirtyDuringRecheck = false;
let transitioning = false; let transitioning = false;
// 对话历史(快照)持久化:刷新后回对话页不丢理解/诊断/复检卡片(用户实测发现 + PM 同意修复)。 // 对话历史(快照)持久化:刷新后回对话页不丢理解/诊断/复检卡片(用户实测发现 + PM 同意修复)。
@@ -936,6 +939,9 @@ function bindAnnotationInteractions(wrap){
wrap.querySelectorAll('.annotation-card').forEach(el=>el.onclick=e=>{ if(!e.target.closest('.why-toggle')) activate(el.dataset.noteId); }); wrap.querySelectorAll('.annotation-card').forEach(el=>el.onclick=e=>{ if(!e.target.closest('.why-toggle')) activate(el.dataset.noteId); });
// 原文中文对照(逐句):对照行与批注同色同序号 —— 点击对照行可联动高亮原文句 // 原文中文对照(逐句):对照行与批注同色同序号 —— 点击对照行可联动高亮原文句
wrap.querySelectorAll('[data-role="orig-translate"]').forEach(btn=>{ btn.onclick = toggleOrigTranslate; }); wrap.querySelectorAll('[data-role="orig-translate"]').forEach(btn=>{ btn.onclick = toggleOrigTranslate; });
// 记住「查看之前的写作建议」的展开状态(左栏重建后恢复,避免翻译完成被收起)
const prior = wrap.querySelector('.prior-guidance');
if(prior) prior.addEventListener('toggle', ()=>{ priorGuidanceOpen = prior.open; });
wrap.querySelectorAll('.ot-line[data-note-id]').forEach(el=>{ el.onclick = () => activate(el.dataset.noteId); }); wrap.querySelectorAll('.ot-line[data-note-id]').forEach(el=>{ el.onclick = () => activate(el.dataset.noteId); });
wrap.querySelectorAll('.why-toggle').forEach(btn=>btn.onclick=e=>{ wrap.querySelectorAll('.why-toggle').forEach(btn=>btn.onclick=e=>{
e.stopPropagation(); e.stopPropagation();
@@ -990,7 +996,7 @@ function renderFocusOriginal(wrap){
<div class="direction-line meaning"><span class="direction-chip meaning">这段在讲什么</span><div class="direction-text">${escapeHtml(meaningOf(current))}</div></div> <div class="direction-line meaning"><span class="direction-chip meaning">这段在讲什么</span><div class="direction-text">${escapeHtml(meaningOf(current))}</div></div>
</div>`; </div>`;
const body = isRevisionTarget(current) const body = isRevisionTarget(current)
? `${visibleMeaning}<details class="prior-guidance"><summary>查看之前的写作建议</summary>${fullDirection}${paper}</details>` ? `${visibleMeaning}<details class="prior-guidance"${priorGuidanceOpen ? ' open' : ''}><summary>查看之前的写作建议</summary>${fullDirection}${paper}</details>`
: fullDirection + paper; : fullDirection + paper;
wrap.className = 'original-workspace'; wrap.className = 'original-workspace';
wrap.innerHTML = `${banner}${body}<div class="context-hint"><div class="context-label">和上下文怎么接</div><div class="context-copy">${escapeHtml(contextHintOf(current))}</div></div>`; wrap.innerHTML = `${banner}${body}<div class="context-hint"><div class="context-label">和上下文怎么接</div><div class="context-copy">${escapeHtml(contextHintOf(current))}</div></div>`;
@@ -1038,9 +1044,14 @@ function updateParagraphSwitcherState(){
} }
function renderOriginalPane(){ function renderOriginalPane(){
const wrap=$('#originalFull'); const wrap=$('#originalFull');
// 重建 DOM 前记住滚动位置:「查看之前的写作建议」展开后点翻译/切视图等
// 都会走到这里,不恢复会导致内容跳回顶部
const body = wrap.closest('.pane-body');
const scrollTop = body ? body.scrollTop : 0;
wrap.innerHTML=''; wrap.innerHTML='';
if(originalView==='focus') renderFocusOriginal(wrap); else renderFullOriginal(wrap); if(originalView==='focus') renderFocusOriginal(wrap); else renderFullOriginal(wrap);
renderParagraphSwitcher(); renderParagraphSwitcher();
if(body) body.scrollTop = scrollTop;
} }
function updateProgress(){ function updateProgress(){
const n = rewrittenCount(); const n = rewrittenCount();