4ong
(Anatol Myshkin)
9월 27, 2021, 2:47오후
1
Discourse에서 많은 페이지가 스크롤 위치를 기억한다는 것을 알 수 있습니다.
하지만 카테고리 페이지는 매번 맨 위에서 열립니다. 그리고 이것이 메인 페이지이고 카테고리가 많을 경우, 사용자 경험(UX)이 최상이 아닙니다.
예를 들어 @markvanlan 님이 작성한 FEATURE: Remember scroll position in private message lists - Pull Request #8212 - discourse/discourse - GitHub 커밋을 확인했습니다.
카테고리 페이지에 대해 동일한 기능을 구현하는 가장 짧은 방법을 아시나요?
이 오래된 주제
The vertical scroll position of the Categories view is lost when a user enters a topic and then hits the back button of the browser. In topic list views it works as expected.
Repro steps:
Go to Categories
Scroll down and click on a topic title in Releases category
Press the browser back button
→ The top of the Category listing is shown, not the Releases category you just scrolled to.
에서 알 수 있듯이, 개발 팀은 다른 페이지와 달리 카테고리 페이지가 맨 위에서 열리도록 유지하는 것을 선호하는 것 같습니다.
따라서 카테고리 스크롤 수정을 별도의 테마 컴포넌트로 구현하는 방법을 찾는 것이 더 나은 것 같습니다. 여러분의 의견으로는 어떤 접근 방식이 가장 좋을까요?
아마 이미 누군가 이를 구현했을 수도 있습니다?
감사합니다!
테마 컴포넌트를 사용하면 이 문제를 해결할 수 있다고 생각합니다. 기술적 배경이 어느 정도인지 확실하지 않지만, 이 문제를 해결하는 기본적인 개요를 설명해 드리겠습니다.
onPageChange API를 사용하여 현재 페이지가 카테고리 페이지인지 확인할 수 있습니다. 그렇다면 localStorage 에서 해당 페이지에서 사용자의 마지막 스크롤 위치를 확인하고, 해당 위치가 존재하면 해당 위치로 스크롤합니다. 그 시점에 윈도우에 이벤트 리스너를 추가하여 사용자의 스크롤 위치를 localStorage에 저장합니다. onPageChange에서 사용자가 카테고리 페이지에 있지 않은 경우, 이벤트 리스너를 제거합니다.
4ong
(Anatol Myshkin)
9월 27, 2021, 3:17오후
3
감사합니다 @markvanlan - 시도해 보겠습니다.
프로그래머이지만 프론트엔드 경험은 적은 편입니다.
이 토픽을 좀 더 열어 두어 주시겠습니까? 이미 이 작업을 해 보신 분이 계실 수도 있습니다.
4ong
(Anatol Myshkin)
10월 4, 2021, 8:45오후
4
지금은 급하게 만든 임시 해결책입니다 - 나중에 누군가에게 도움이 될지도 모릅니다.
<script type="text/discourse-plugin" version="0.8">
api.onPageChange((url) => {
window.removeEventListener("scroll", saveScroll, {passive: true,});
if (url === "/" || url === "/categories"){
restoreScroll();
window.addEventListener("scroll", saveScroll, {passive: true,});
}
});
function restoreScroll() {
var pos = sessionStorage.getItem("categoriesScrollPosition");
if (pos != 0) {
window.scrollTo(0, pos);
}
}
function saveScroll() {
if (window.scrollY != 0) {
sessionStorage.setItem("categoriesScrollPosition", window.scrollY + 1);
}
}
</script>