From ae04b403d68ac3399788d79dd5902765f2dc2f39 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 5 Oct 2026 20:01:14 +0900 Subject: [PATCH] =?UTF-8?q?fix(ui):=2051-8=20=EC=98=A4=EB=A5=B8=EC=AA=BD?= =?UTF-8?q?=20=ED=8C=A8=EB=84=90=20=EB=86=92=EC=9D=B4=20=E2=80=94=20?= =?UTF-8?q?=EC=B9=B8=20=ED=81=AC=EA=B8=B0=EA=B0=80=20=EB=B0=94=EB=80=8C?= =?UTF-8?q?=EB=A9=B4=20=EB=8B=A4=EC=8B=9C=20=EC=9E=BC(M01=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=83=81=EC=84=B8=20240=20=EA=B3=A0=EC=A0=95=20?= =?UTF-8?q?=ED=95=B4=EC=86=8C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 원인: 패널 높이를 붙은 직후 한 번만 잼 · M01 은 내용이 늦게 차 그때 칸이 짧아 최소 240 · 스크롤·창 크기 바뀜 전까지 그대로 - 고침: 패널 · 부모 칸 크기 지켜봄(ResizeObserver) — 다시 붙음 · 내용 늦게 참에도 다시 잼 - 51-1 확인: 스크롤 알림 없는 「그대로」 줄 추가(알림이 흠을 가림) Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01NPJGtfXo6GMbcpiboQC4uK --- resources/tester/ui_checks/51-1_오른쪽패널_높이.js | 11 ++++++++++- ui_template/ui_template_side_panels.ts | 10 ++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/resources/tester/ui_checks/51-1_오른쪽패널_높이.js b/resources/tester/ui_checks/51-1_오른쪽패널_높이.js index ba3fabdd3..1a447c13b 100644 --- a/resources/tester/ui_checks/51-1_오른쪽패널_높이.js +++ b/resources/tester/ui_checks/51-1_오른쪽패널_높이.js @@ -1,7 +1,7 @@ /* 51-1 — 오른쪽 패널(공용 ui_template_side_panels) 높이 = innerHeight − 머리띠 · 스크롤 처음/중간/끝 화면 안 * 시작 화면: 패널이 이미 열린 상세 화면 하나(M02 일위대가 상세 · M02 면적산출 · M01 로직 상세 중 하나) · 화면마다 한 번씩 부름 * 부르는 법: orca eval --expression "$(tr '\n' ' ' < 이 파일)" (async 식 · JSON 글을 돌려줌) - * 기대: ok = true · h = want(innerHeight − max(머리띠, 칸 위)) ±2 · 칸이 올라가 붙은 뒤는 innerHeight − 머리띠 · inView = 처음·중간·끝 모두 true + * 기대: ok = true · h = want(innerHeight − max(머리띠, 칸 위)) ±2 · 칸이 올라가 붙은 뒤는 innerHeight − 머리띠 · inView = 그대로·처음·중간·끝 모두 true */ (async () => { const w = (ms) => new Promise((r) => setTimeout(r, ms)); @@ -38,7 +38,16 @@ }; }; const was = scroller.scrollTop; + // 스크롤 알림 없이 지금 높이 — 내용이 늦게 차도 스스로 다시 쟀는지(알림을 쏘면 가려짐 · 가린 탭은 먼저 orca screenshot 으로 한 장 그림) + const r0 = sp.getBoundingClientRect(); + const still = { + name: "그대로", + h: Math.round(r0.height), + want: Math.round(innerHeight - Math.max(head, sp.parentElement.getBoundingClientRect().top)), + inView: r0.top >= head - 2 && r0.bottom <= innerHeight + 2, + }; const rows = [ + still, await sample("처음", 0), await sample("중간", Math.round(max / 2)), await sample("끝", max), diff --git a/ui_template/ui_template_side_panels.ts b/ui_template/ui_template_side_panels.ts index 2041a5c04..93aa4c17c 100644 --- a/ui_template/ui_template_side_panels.ts +++ b/ui_template/ui_template_side_panels.ts @@ -185,10 +185,18 @@ function scroller(node: HTMLElement): HTMLElement | null { */ function followView(node: HTMLElement): void { const ref = new WeakRef(node); // 떼었다 다시 붙이는 화면(M01)도 있어 떼어져도 듣기는 남김 · 버려지면 그침 + // 다시 붙음 · 칸 내용이 늦게 차 칸 크기가 바뀜(스크롤 없이) → 다시 잼 + const sized = new ResizeObserver(() => place()); + let watched: Element | null = null; const place = (): void => { const root = ref.deref(); if (!root) return stop(); if (!root.isConnected) return; + if (root.parentElement && root.parentElement !== watched) { + if (watched) sized.unobserve(watched); + watched = root.parentElement; + sized.observe(watched); + } const box = scroller(root)?.getBoundingClientRect(); const head = document.querySelector(".app-header")?.getBoundingClientRect().bottom ?? 0; const view = Math.max(head, box?.top ?? 0); @@ -206,8 +214,10 @@ function followView(node: HTMLElement): void { const stop = (): void => { window.removeEventListener("scroll", place, true); window.removeEventListener("resize", place); + sized.disconnect(); }; window.addEventListener("scroll", place, true); window.addEventListener("resize", place); + sized.observe(node); setTimeout(place); // 붙은 뒤 한 번 }