홈 슬라이드 카드 클릭 처리 수정
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
# 업데이트 요약
|
||||
|
||||
## v1.9.27
|
||||
|
||||
- 홈 Featured와 Pages 슬라이드 카드 클릭이 링크 이동으로 동작하도록 포인터 캡처 처리를 보정했다.
|
||||
|
||||
## v1.9.26
|
||||
|
||||
- 홈 Featured와 Pages 카드 클릭이 드래그 처리에 막히지 않도록 수정했다.
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# 의사결정 이력
|
||||
|
||||
## 2026-07-01 v1.9.27 — 캐러셀 포인터 캡처는 드래그 확정 뒤에만 적용한다
|
||||
|
||||
홈 Featured와 Pages 선반은 포인터 다운 시점에 스크롤 트랙이 포인터 캡처를 가져가면 실제 이동이 없는 일반 클릭도 링크 활성화 흐름이 깨질 수 있다. 따라서 포인터 이동이 임계값을 넘은 뒤에만 포인터 캡처를 적용해, 단순 클릭은 링크 이동으로 처리하고 드래그 확정 후에만 카드 밖 이동 추적을 강화한다.
|
||||
|
||||
## 2026-07-01 v1.9.26 — 캐러셀 클릭과 드래그는 이동 거리로 구분한다
|
||||
|
||||
홈 Featured와 Pages 선반은 링크 카드 위에서 드래그 이동도 지원하므로, 포인터를 누른 즉시 기본 동작을 막으면 일반 클릭까지 링크 이동이 되지 않는다. 따라서 포인터 이동이 임계값을 넘은 경우에만 드래그로 전환하고, 단순 클릭은 브라우저 링크 동작을 그대로 허용한다. 오른쪽 사이드 구분선은 sticky 사이드바가 아니라 레이아웃 컬럼에서 그려 긴 게시물에서도 문서 높이만큼 이어지게 한다.
|
||||
|
||||
@@ -197,7 +197,7 @@
|
||||
|
||||
| 파일 | 화면 |
|
||||
|------|------|
|
||||
| pages/index.vue | 홈, `site_settings` 커버가 있을 때만 라이트·다크 이미지 지원 `HomeHero`, Featured/Latest, 사이트 설정 표시개수 기준 Latest·Featured·Pages 데이터 제한, 홈 표시 페이지를 섹션별 도서 진열장형 Pages 선반으로 노출, Featured와 Pages 선반의 독립 이전·다음 버튼 및 문서 레벨 포인터 추적 기반 드래그 슬라이드·스냅(이동 임계값 미만 클릭은 링크 이동), Pages 선반 ResizeObserver 기반 버튼 상태 갱신, Pages 카드 hover 상단 여백 보정, Latest 피드 Compact 기본값·List·Cards 보기, Compact 모바일 썸네일 80px 정사각형·Compact/List 설명 2줄 제한, Latest 메타는 태그가 있을 때만 링크 배지 표시, 카드 오른쪽 아래 화살표는 게시물 상세 링크, Featured는 추천 글이 있을 때만 표시하며 이미지 없는 추천 글은 제목 placeholder 썸네일과 모바일 터치 가로 스크롤·스냅, 끝에서 화살표 비활성 |
|
||||
| pages/index.vue | 홈, `site_settings` 커버가 있을 때만 라이트·다크 이미지 지원 `HomeHero`, Featured/Latest, 사이트 설정 표시개수 기준 Latest·Featured·Pages 데이터 제한, 홈 표시 페이지를 섹션별 도서 진열장형 Pages 선반으로 노출, Featured와 Pages 선반의 독립 이전·다음 버튼 및 문서 레벨 포인터 추적 기반 드래그 슬라이드·스냅(이동 임계값 미만 클릭은 링크 이동, 포인터 캡처는 드래그 확정 뒤 적용), Pages 선반 ResizeObserver 기반 버튼 상태 갱신, Pages 카드 hover 상단 여백 보정, Latest 피드 Compact 기본값·List·Cards 보기, Compact 모바일 썸네일 80px 정사각형·Compact/List 설명 2줄 제한, Latest 메타는 태그가 있을 때만 링크 배지 표시, 카드 오른쪽 아래 화살표는 게시물 상세 링크, Featured는 추천 글이 있을 때만 표시하며 이미지 없는 추천 글은 제목 placeholder 썸네일과 모바일 터치 가로 스크롤·스냅, 끝에서 화살표 비활성 |
|
||||
| pages/posts/index.vue | 게시물 전체 목록, 사이트 설정 Posts 표시개수 기준 서버 페이지네이션, 태그는 있을 때만 카드 메타에 링크로 표시 |
|
||||
| pages/posts/[slug].vue | `/post/:slug` 리다이렉트 |
|
||||
| pages/post/[slug].vue | 블로그 글 상세, 첫 태그가 있을 때만 메타 행에 태그 링크, H1~H3 본문 제목을 오른쪽 TOC 상태로 제공, 공개 회원 로그인 세션의 회원이 글쓴이(`author_id`)이면 공유 버튼 옆 새 탭 편집 링크 표시, 게시물 SEO/OG 메타 출력(요약 없으면 본문 fallback), 공유 모달(X/Bluesky/Facebook/LinkedIn/Email/링크복사), 회원 댓글 섹션 |
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
- Featured 대표 이미지가 게시물 업로드 이미지이고 카드 썸네일이 생성되어 있으면 원본 대신 `featuredImageThumbnail`을 우선 표시한다.
|
||||
- 모바일 터치: `touch-pan-x`, `-webkit-overflow-scrolling: touch`, `overscroll-x-contain`으로 가로 스크롤 우선·부모로의 스크롤 전파 완화.
|
||||
- 헤더의 이전·다음 화살표는 `scrollLeft`와 최대 스크롤 거리로 양 끝에서 `disabled` 처리하며, `scroll` 이벤트와 `ResizeObserver`로 동기화한다. Pages 선반은 각 선반의 스크롤 컨테이너와 카드 크기 변화를 감시해 이미지 로딩·반응형 폭 변화 후에도 버튼 상태를 다시 계산한다.
|
||||
- 마우스/트랙패드 환경에서는 카드 트랙을 직접 드래그해 넘길 수 있고, 드래그 종료 시 가까운 카드 위치로 스냅한다. 트랙 안의 이미지 기본 드래그와 텍스트 선택은 막아 캐러셀 조작을 우선하며, 클릭과 구분되는 이동 임계값을 넘었을 때만 드래그로 처리한다. 드래그 중 포인터가 카드 밖으로 이동해도 문서 레벨 포인터 추적으로 조작을 유지한다. 드래그 직후에는 카드 링크 클릭을 억제해 의도치 않은 이동을 막는다.
|
||||
- 마우스/트랙패드 환경에서는 카드 트랙을 직접 드래그해 넘길 수 있고, 드래그 종료 시 가까운 카드 위치로 스냅한다. 트랙 안의 이미지 기본 드래그와 텍스트 선택은 막아 캐러셀 조작을 우선하며, 클릭과 구분되는 이동 임계값을 넘었을 때만 드래그로 처리한다. 포인터 캡처는 드래그가 확정된 뒤에만 적용해 일반 클릭의 링크 이동을 막지 않는다. 드래그 중 포인터가 카드 밖으로 이동해도 문서 레벨 포인터 추적으로 조작을 유지한다. 드래그 직후에는 카드 링크 클릭을 억제해 의도치 않은 이동을 막는다.
|
||||
|
||||
### 홈 Latest 피드
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# 업데이트 이력
|
||||
|
||||
## v1.9.27
|
||||
|
||||
- 홈 Featured·Pages 캐러셀에서 포인터 캡처가 일반 클릭까지 가로채 링크가 열리지 않던 문제 수정.
|
||||
|
||||
## v1.9.26
|
||||
|
||||
- 홈 Featured·Pages 캐러셀 클릭이 드래그 시작 처리에 막혀 링크가 열리지 않던 문제 수정.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sori.studio",
|
||||
"version": "1.9.26",
|
||||
"version": "1.9.27",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"imports": {
|
||||
|
||||
@@ -236,7 +236,7 @@ const carouselDragState = reactive({
|
||||
startX: 0,
|
||||
startScrollLeft: 0,
|
||||
lastDeltaX: 0,
|
||||
dragThreshold: 4,
|
||||
dragThreshold: 10,
|
||||
moved: false,
|
||||
suppressClick: false
|
||||
})
|
||||
@@ -606,13 +606,10 @@ const startCarouselDrag = (event, key) => {
|
||||
carouselDragState.startX = event.clientX
|
||||
carouselDragState.startScrollLeft = track.scrollLeft
|
||||
carouselDragState.lastDeltaX = 0
|
||||
carouselDragState.dragThreshold = event.pointerType === 'mouse' ? 4 : 8
|
||||
carouselDragState.dragThreshold = event.pointerType === 'mouse' ? 10 : 12
|
||||
carouselDragState.moved = false
|
||||
carouselDragTrack = track
|
||||
bindCarouselDragDocumentEvents()
|
||||
if (track.setPointerCapture) {
|
||||
track.setPointerCapture(event.pointerId)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -632,8 +629,11 @@ const moveCarouselDrag = (event) => {
|
||||
|
||||
const deltaX = event.clientX - carouselDragState.startX
|
||||
carouselDragState.lastDeltaX = deltaX
|
||||
if (Math.abs(deltaX) >= carouselDragState.dragThreshold) {
|
||||
if (!carouselDragState.moved && Math.abs(deltaX) >= carouselDragState.dragThreshold) {
|
||||
carouselDragState.moved = true
|
||||
if (track.setPointerCapture) {
|
||||
track.setPointerCapture(event.pointerId)
|
||||
}
|
||||
}
|
||||
|
||||
if (!carouselDragState.moved) {
|
||||
|
||||
Reference in New Issue
Block a user