페이지를 옮겼을 때 보고 있던 메뉴가 처음으로 돌아오면 사용자는 방금 찾은 대상을 다시 찾아야 한다. K-POP PULSE의 당시 수정 기록에는 같은 목록을 한 벌로 합치고 실제 CSS 방향을 읽어 가로·세로 위치를 따로 기억하는 선택이 남아 있다. 나는 이 판단을 다른 홈페이지에서도 쓸 수 있는 작은 모듈로 발전시켰다.
여기서 공유하는 것은 새로 작성한 코드와 합성 대상의 작동 예제다. 원본 프로그램을 복원한 파일은 아니다. 선택·위치·저장 실패의 핵심 상태는 검사했고, 새 화면의 PC·작은 폭·키보드 조작은 아직 검수 대기 중이다. 사용하는 사이트의 실제 이동 흐름까지 확인하는 출발점으로 남긴다.
대상과 보던 자리를 다른 값으로 둔다
선택한 대상은 페이지가 무엇을 보여 주는지와 연결된다. 메뉴에서 보던 자리는 목록의 어느 부분을 찾고 있었는지와 연결된다. 대상 하나의 식별자만 저장하면 스크롤 위치가 사라지고, 위치만 저장하면 목록의 순서가 바뀌었을 때 다른 대상을 선택한 것처럼 해석할 수 있다.
새 핵심 함수는 selectedId와 positions의 x·y를 따로 둔다. 실제 페이지에서는 현재 주소에 맞는 식별자를 전달하고 저장된 선택 때문에 사용자를 다른 주소로 다시 보내지 않는다. 목록에서 선택한 대상의 표시와 페이지의 내용이 맞는지는 연결하는 사이트가 확인한다.
CSS가 한 목록의 방향을 정하게 한다
작은 폭과 큰 폭마다 같은 목록을 다시 출력하면 수정할 목록과 이벤트가 늘어난다. 새 예제는 nav 한 벌의 방향만 row와 column으로 바꾼다. 프로그램은 계산된 flex-direction을 읽고 현재 축을 선택한다. 방향 기준을 화면 코드와 프로그램에 서로 다르게 적지 않는 구조다.
아래 CSS는 적용의 출발점이다. 전환 폭과 최대 높이는 사이트의 본문과 대상 수에 맞게 정해야 한다. 이 모듈은 정상 LTR 가로·세로 배치에 한정하며 역방향·RTL·가상 목록·드래그 정렬은 포함하지 않는다. 원본 사이트의 모든 탐색 기능을 재현했다는 뜻도 아니다.
코드와 구현 살펴보기
목록 한 벌의 방향만 바꾸는 새 CSS 예시. 전환 폭은 사이트별로 조정한다.
.subject-rail { display:flex; flex-direction:row; direction:ltr; overflow:auto; }
.subject-rail > * { flex:0 0 auto; }
@media (min-width: 900px) {
.subject-rail { flex-direction:column; max-height:20rem; }
}방향마다 위치를 나누고 현재 길이에 맞춰 보정한다
가로 목록에서 이동한 100픽셀과 세로 목록의 100픽셀은 같은 장면이 아니다. 그래서 방향을 왕복하면 해당 방향에 남긴 값을 복원한다. 데이터가 줄거나 화면이 커져 실제 이동 가능한 범위가 짧아지면 저장된 값을 현재 범위 안으로 보정한다.
대상은 배열 번호가 아니라 변하지 않는 식별자로 연결한다. 순서를 바꿔도 같은 ID는 같은 대상으로 읽고, 선택한 ID가 목록에서 빠졌으면 선택을 비운다. 핵심 함수의 목록 갱신과 화면 DOM의 갱신은 다르다. 실제 자식 요소가 바뀌면 기존 연결을 해제한 뒤 새 목록에 다시 연결한다.
저장소가 막혀도 같은 화면의 탐색은 남긴다
브라우저 저장소를 읽거나 쓰는 일은 실패할 수 있다. 새 모듈은 그 예외를 잡고 현재 연결의 메모리로 이어간다. 화면 안에서 선택과 위치는 계속 사용할 수 있지만 페이지를 다시 연결하거나 새로고침한 뒤에도 보존됐다고 말하지 않는다. 실행 예제에는 현재 모드를 표시한다.
본문의 HTML 예제는 관리자와 다른 실행 프레임에 있다. 이 프레임에서 저장소가 막혀 있더라도 지속 저장을 위해 관리자 권한을 공유하지 않는다. 자신의 사이트에 붙일 때는 저장 기간과 키를 정하고 localStorage 접근을 보호해 전달한다. 탐색 기억에 로그인 정보나 비밀 값을 넣을 필요는 없다.
실제 이동의 책임은 사이트에 남긴다
아래 코드는 실제 라우트의 대상 ID와 별도의 저장 키를 넘기는 연결 예시다. currentRouteSubjectId는 사이트가 현재 주소에서 확인한 값을 공급해야 한다. 모듈은 링크의 기본 이동을 가로채지 않는다. 새 예제의 번호 버튼은 내용만 바꾸며 재연결 버튼도 실제 다른 페이지 이동을 시험하는 기능은 아니다.
스크롤은 프레임 단위로 모아 저장하고 선택·pagehide 때 현재 위치를 즉시 기록한다. 연결을 없앨 때는 이벤트·관찰자·예약 프레임을 정리한다. 실제 사이트에서는 뒤로 가기, 새로고침, 화면 폭 변경, 다른 목록으로의 이동과 키보드 포커스를 이어서 검사해야 한다.
코드와 구현 살펴보기
실제 라우트의 ID를 공급하는 새 연결 예시. 아래 변수는 사이트가 정의한다.
import {attachRail} from './rail-memory.mjs';
let storage = null;
try { storage = window.localStorage; } catch {}
const controller = attachRail(document.querySelector('.subject-rail'), {
key: 'your-site:subject-rail:v1',
storage,
currentId: currentRouteSubjectId // Supply the actual route's ID, or null.
});
// Before replacing the list DOM:
// controller.destroy(); then attach the replacement rail.코드와 예제를 받아 자신의 흐름에서 확인한다
다운로드에는 핵심 모듈, 한영 독립 HTML, 설명과 Node 재현 검사가 있다. 선택 보존·방향별 값·짧아진 범위·잘못된 저장 데이터·목록 변경·저장 실패 등 16개 합성 핵심 검사를 통과했다. 이 검사는 렌더링과 이벤트 순서, 실제 페이지 사이의 저장을 대신하지 않는다.
이번 Studio 브라우저 검사에서는 한국어·영어 예제의 960px·390px 프레임에서 방향 전환, 실제 스크롤과 대상 선택, 방향별 위치 복원을 확인했다. 공개 샌드박스의 메모리 모드에서는 재연결 뒤 초기화되는 것도 확인했다. 별도로 같은 핵심 코드를 실제 브라우저 저장소의 새 시험 키로 실행해 새로고침 뒤 선택과 두 위치가 남는지 확인하고 그 키를 원상복구했다. 실제 사이트 이동·드래그 정렬·물리 기기 전체 화면 검수는 이 검사에 포함하지 않는다.