들어가며
최근 모바일 애플리케이션에서는 앱 내부에서 웹페이지를 띄우는 웹뷰(WebView) 기능을 많이 활용하고 있습니다. 이때, 웹뷰 안에서 foreground와 background 전환을 감지해야 하는 경우가 종종 발생합니다. 예를 들어, 사용자가 잠시 다른 앱을 사용하다가 다시 우리 서비스로 돌아오는 경우, 그 전환을 정확히 감지해야 할 수 있습니다. 본 포스팅에서는 이러한 요구사항을 해결하기 위한 시도와 해결 방안에 대하여 알아보고자 합니다.
첫 번째 접근: window.onFocus
처음에는 window.onFocus 이벤트를 활용하여 foreground와 background 전환을 감지하려고 했습니다. 일반적으로 onFocus는 윈도우나 탭이 focus를 받을 때 호출됩니다. 하지만, 모바일 환경에서는 이 방법이 제대로 작동하지 않는다는 문제를 발견했습니다. 모바일 브라우저에서는 웹뷰가 백그라운드에서 포어그라운드로 돌아올 때, 웹페이지를 한 번 터치해야만 포커스가 감지되는 현상이 발생합니다. 이러한 동작은 사용자가 원활하게 앱을 돌아오는 경험을 제공하지 못하게 만듭니다.
따라서 window.onFocus 이벤트는 모바일 웹뷰에서의 전환을 감지하는 데 적합하지 않아 다른 접근 방법을 찾아보았습니다.
올바른 접근: document.hidden
모바일 웹뷰에서 포어그라운드와 백그라운드 전환을 정확하게 감지하려면, document.hidden 속성을 활용하는 방법이 훨씬 더 적합합니다. document.hidden은 페이지가 보이는 상태인지 아닌지를 체크할 수 있게 해주는 속성으로, 웹 페이지가 백그라운드로 들어갔을 때나 포어그라운드로 돌아왔을 때 이를 정확히 감지할 수 있습니다. 이를 통해 우리는 웹뷰가 백그라운드에서 포어그라운드로, 혹은 그 반대로 전환될 때 필요한 작업을 처리할 수 있습니다.
예제 코드
아래는 document.hidden을 활용하여 포어그라운드와 백그라운드 전환을 감지하는 코드 예제입니다. 이 코드는 visibilitychange 이벤트를 통해 전환을 감지하고, 그에 따라 적절한 로직을 실행할 수 있도록 합니다.
import { useEffect } from 'react';
const usePageVisibility = () => {
useEffect(() => {
const handleVisibilityChange = () => {
if (document.hidden) {
// 페이지가 백그라운드로 전환
} else {
// 페이지가 포어그라운드로 전환
}
};
// 이벤트 리스너 등록
document.addEventListener('visibilitychange', handleVisibilityChange);
// 클린업 함수
return () => {
document.removeEventListener('visibilitychange', handleVisibilityChange);
};
}, []);
return null;
};
export default usePageVisibility;
위 코드에서 visibilitychange 이벤트는 문서의 가시성 상태가 바뀔 때마다 호출됩니다. document.hidden이 true이면 페이지가 백그라운드로 들어갔음을 의미하고, false이면 페이지가 포어그라운드로 돌아왔음을 의미합니다.
이 코드를 커스텀 훅으로 만들게 되면 백그라운드, 포어그라운드 전환 시 실행되어야 하는 동작을 넘기는 것으로 간편하게 여러 곳에서 사용할 수 있습니다.
'Web' 카테고리의 다른 글
[Next.js] next/head 안에 next/script를 넣으면 동작하지 않는다? (0) | 2024.11.27 |
---|---|
[Web] 웹 페이지 성능 개선을 위한 도구 Lighthouse 알아보기 (0) | 2024.11.18 |
[Next.js] 14 버전 favicon(파비콘) 미적용 에러 해결하기 (0) | 2024.09.11 |
[TanStack Query] TanStack Query(React Query)의 stale time과 cache time은 무엇일까? (0) | 2024.08.05 |
[HTML/CSS] "Warning: validateDOMNesting(...): <div> cannot appear as a descendant of <p>." 경고 해결하기 (2) | 2024.07.14 |