페이지 이동 중 중복 클릭 차단 추가

- 이동 중 site-navigating 클래스로 링크·버튼 pointer-events를 끄는 클라이언트 플러그인 추가
- 게시물 재클릭 시 상단 점프 문제 해결, 안전 타임아웃으로 잠금 잔존 방지
- v1.10.34

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-03 18:36:13 +09:00
parent 16343b62c7
commit 5db41e9883
5 changed files with 58 additions and 1 deletions

View File

@@ -94,6 +94,16 @@
overflow: hidden;
}
html.site-navigating {
cursor: progress;
}
html.site-navigating a,
html.site-navigating button,
html.site-navigating [role="button"] {
pointer-events: none;
}
body {
min-width: 320px;
margin: 0;

View File

@@ -361,6 +361,7 @@
| server/routes/admin/api/analytics/range-detail.get.js | 관리자 통계 추이 날짜·구간 상세 API |
| plugins/site-analytics.client.js | 공개 라우트 pageview·heartbeat·read 클라이언트 전송 |
| plugins/bfcache-page-restore.client.js | 뒤로가기 캐시(bfcache) 복원 시 라우터 경로와 실제 URL 어긋남을 감지해 새로고침(HTML 문서 모드 페이지 이동 후 뒤로가기 잔상 방지) |
| plugins/navigation-lock.client.js | 페이지 이동 중 `html.site-navigating` 클래스로 링크·버튼 클릭을 잠가 중복 클릭 차단(안전 타임아웃 포함) |
## 데이터베이스

View File

@@ -1,5 +1,11 @@
# 업데이트 이력
## v1.10.34
- 페이지 이동 중 링크·버튼 중복 클릭(연타) 차단 추가.
- 이동 중 `html.site-navigating` 클래스로 상호작용 요소 pointer-events를 끄는 클라이언트 플러그인 `navigation-lock.client.js` 추가(예외 방지 안전 타임아웃 포함).
- 게시물 클릭 후 재클릭 시 상단으로 점프하던 문제 해결.
## v1.10.33
- HTML 문서 모드 페이지 뒤로가기 시 홈으로 돌아가지 못하던 문제를 근본 수정.

View File

@@ -1,6 +1,6 @@
{
"name": "sori.studio",
"version": "1.10.33",
"version": "1.10.34",
"private": true,
"type": "module",
"imports": {

View File

@@ -0,0 +1,40 @@
/**
* 페이지 이동 중 링크·버튼 클릭을 잠가 중복 클릭(연타)을 막는다.
*
* 이동 시작 시 `html.site-navigating` 클래스를 붙여 상호작용 요소의 pointer-events를 끄고,
* 이동 종료·실패 시 해제한다. 예외로 클래스가 남는 것을 막기 위해 안전 타임아웃을 둔다.
*/
const NAVIGATION_LOCK_CLASS = 'site-navigating'
const NAVIGATION_LOCK_TIMEOUT_MS = 10000
export default defineNuxtPlugin((nuxtApp) => {
const root = document.documentElement
/** @type {ReturnType<typeof setTimeout> | null} */
let releaseTimer = null
/**
* 이동 잠금을 건다(안전 타임아웃 포함).
* @returns {void}
*/
const lockNavigation = () => {
root.classList.add(NAVIGATION_LOCK_CLASS)
clearTimeout(releaseTimer)
releaseTimer = setTimeout(() => {
root.classList.remove(NAVIGATION_LOCK_CLASS)
}, NAVIGATION_LOCK_TIMEOUT_MS)
}
/**
* 이동 잠금을 해제한다.
* @returns {void}
*/
const unlockNavigation = () => {
clearTimeout(releaseTimer)
releaseTimer = null
root.classList.remove(NAVIGATION_LOCK_CLASS)
}
nuxtApp.hook('page:loading:start', lockNavigation)
nuxtApp.hook('page:loading:end', unlockNavigation)
})