창 관리

브라우저 외부의 PWA는 자체 창을 관리합니다. 이 장에서는 운영체제 내에서 창을 관리하기 위한 API와 기능을 이해합니다.

PWA 창

PWA에서 관리하는 자체 창에서 실행하면 해당 운영체제의 모든 창의 장점과 책임이 있습니다(예:

  • Windows 또는 ChromeOS와 같은 멀티 윈도우 운영체제에서 창의 크기를 조절하고 창을 움직이는 기능
  • iPadOS 분할 모드 또는 Android 화면 분할 모드에서와 같이 다른 앱 창과 화면 공유
  • 데스크톱의 도크, 작업 표시줄, Alt-Tab 메뉴, 휴대기기의 멀티태스킹 창 목록에 표시됩니다.
  • 언제든지 창을 최소화하고, 화면과 데스크톱 간에 창을 이동하고, 창을 닫을 수 있는 기능

창 이동 및 크기 조절

PWA 창의 크기는 원하는 대로 설정할 수 있으며 데스크톱 운영체제의 화면 어디에나 배치할 수 있습니다. 기본적으로 사용자가 설치 후 처음으로 PWA를 열면 PWA의 기본 창 크기가 현재 화면의 일정 비율이며, 최대 해상도는 1920x1080이 화면 왼쪽 상단에 배치됩니다.

사용자는 창을 이동하고 크기를 조절할 수 있으며 브라우저는 마지막 환경설정을 기억하므로 사용자가 다음에 앱을 열면 창이 이전 사용의 크기와 위치를 유지합니다.

매니페스트 내에서 PWA의 기본 크기와 위치를 정의할 방법은 없습니다. JavaScript API를 사용하는 경우에만 창의 위치와 크기를 변경할 수 있습니다. 코드에서 window 객체의 moveTo(x, y)resizeTo(x, y) 함수를 사용하여 자체 PWA 창을 이동하고 크기를 조절할 수 있습니다.

예를 들어 다음을 사용하여 PWA가 로드될 때 PWA 창의 크기를 조절하고 이동할 수 있습니다.

document.addEventListener("DOMContentLoaded", event => {
   // we can move only if we are not in a browser's tab
   isBrowser = matchMedia("(display-mode: browser)").matches;
   if (!isBrowser) {
      window.moveTo(16, 16);
      window.resizeTo(800, 600);
   }
});

window.screen 객체를 사용하여 현재 화면 크기와 위치를 쿼리할 수 있습니다. window 객체의 resize 이벤트를 사용하여 창 크기가 조절되는 시점을 감지할 수 있습니다. 창 이동을 캡처하는 이벤트가 없으므로 위치를 자주 쿼리하는 옵션을 사용할 수 있습니다.

다른 사이트 탐색

사용자를 PWA 범위를 벗어나는 외부 사이트로 보내려면 location.href를 사용하거나 호환되는 플랫폼에서 새 창을 열어 표준 <a href> HTML 요소를 사용하면 됩니다.

현재 모든 브라우저에서 PWA가 설치된 경우 매니페스트 범위를 벗어난 URL로 탐색하면 PWA의 브라우저 엔진이 창 컨텍스트 내에서 인앱 브라우저를 렌더링합니다.

인앱 브라우저의 기능은 다음과 같습니다.

  • 콘텐츠 위에 표시됩니다.
  • 현재 출처, 창 제목, 메뉴를 보여주는 정적 URL 표시줄이 있습니다. 일반적으로 매니페스트의 theme_color로 테마가 설정됩니다.
  • 컨텍스트 메뉴에서 해당 URL을 브라우저에서 열 수 있습니다.
  • 사용자는 브라우저를 닫거나 뒤로 돌아갈 수 있습니다.

범위 밖에 있는 URL을 탐색할 때 데스크톱 PWA에서 실행되는 인앱 브라우저입니다.

iPhone의 인앱 브라우저가 독립형 PWA 내에서 범위 밖에 있는 URL을 탐색하는 경우

독립형 PWA의 범위를 벗어난 URL을 탐색할 때 Android의 인앱 브라우저

승인 흐름

많은 웹 인증 및 승인 흐름은 OAuth 2.0 사용과 같이 사용자를 다른 출처의 다른 URL로 리디렉션하여 PWA의 출처로 반환할 토큰을 획득하는 것을 포함합니다.

이 경우 인앱 브라우저는 다음 프로세스를 따릅니다.

  1. 사용자가 PWA를 열고 로그인을 클릭합니다.
  2. PWA는 사용자를 PWA 범위를 벗어나는 URL로 리디렉션하므로 렌더링 엔진이 PWA 내에서 인앱 브라우저를 엽니다.
  3. 사용자는 언제든지 인앱 브라우저를 취소하고 PWA로 돌아갈 수 있습니다.
  4. 사용자가 인앱 브라우저에 로그인합니다. 인증 서버는 사용자를 PWA 출처로 리디렉션하여 토큰을 인수로 전송합니다.
  5. 인앱 브라우저는 PWA 범위에 속하는 URL을 감지하면 자동으로 닫힙니다.
  6. 엔진이 기본 PWA 창 탐색을 인앱 브라우저에 있는 동안 인증 서버가 이동한 URL로 리디렉션합니다.
  7. PWA가 토큰을 가져와 토큰을 저장하고 PWA를 렌더링합니다.

브라우저 탐색 강제

인앱 브라우저가 아닌 URL로 브라우저를 강제로 열려면 <a href> 요소의 _blank 타겟을 사용하면 됩니다. 이 방법은 데스크톱 PWA에서만 작동합니다. 휴대기기에서는 URL로 브라우저를 여는 옵션이 없습니다.

function openBrowser(url) {
    window.open("url", "_blank", "");
}

새 창 열기

데스크톱에서는 사용자가 동일한 PWA의 창을 두 개 이상 열 수 있습니다. 마치 동일한 URL의 브라우저 탭을 두 개 여는 것처럼 각 창은 동일한 start_url로 이동하는 다른 탐색 메뉴입니다. 사용자는 PWA 메뉴에서 '파일'과 '새 창'을 차례로 선택하고, PWA 코드에서 open() 함수를 사용하여 새 창을 열 수 있습니다. 자세한 내용은 문서를 확인하세요.

function openNewWindow() {
    window.open("/", "new-window", "width=600,height=600");
}

데스크톱 운영체제에서 여러 창이 열려 있는 동일한 설치된 PWA

iOS 또는 iPadOS의 PWA 창 내에서 open()를 호출하면 null이 반환되고 창이 열리지 않습니다. Android에서 새 창을 열면 URL이 PWA의 범위 내에 있더라도 URL의 새 인앱 브라우저가 생성되며, 이 브라우저는 일반적으로 외부 탐색 환경을 트리거하지 않습니다.

창 제목

<title> 요소는 브라우저 탭 내 공간이 제한되어 있으므로 주로 SEO 목적으로 사용되었습니다. PWA에서 브라우저에서 창으로 이동하면 모든 제목 표시줄 공간을 사용할 수 있습니다.

제목 표시줄의 콘텐츠를 정의할 수 있습니다.

  • HTML <title> 요소에 정적으로 삽입
  • 언제든지 document.title 문자열 속성을 동적으로 변경합니다.

데스크톱 PWA에서는 제목이 필수이며 창의 제목 표시줄에 사용되며 경우에 따라 작업 관리자 또는 멀티태스킹 선택에 사용됩니다. 단일 페이지 애플리케이션의 경우 모든 경로에서 제목을 업데이트하는 것이 좋습니다.

탭 모드

탭 모드​라는 실험용 기능을 사용하면 PWA에 웹브라우저와 유사한 탭 기반 디자인을 적용할 수 있습니다. 이 경우 사용자는 동일한 PWA에서 여러 탭을 열 수 있지만 다음 동영상에서 볼 수 있듯이 모두 동일한 운영체제 창에 연결됩니다.

이 실험용 기능에 관한 자세한 내용은 PWA용 탭형 애플리케이션 모드를 참고하세요.

창 컨트롤 오버레이

<title> 요소 또는 document.title 속성의 값을 정의하여 창의 제목을 변경할 수 있다고 언급했습니다. 하지만 항상 문자열 값입니다. HTML, CSS, 이미지를 사용하여 원하는 대로 제목 표시줄을 디자인할 수 있다면 어떨까요? 여기에서 데스크톱 PWA용 Microsoft Edge 및 Google Chrome의 새로운 실험용 기능인 창 컨트롤 오버레이가 사용됩니다.

이 기능에 관한 자세한 내용은 PWA 제목 표시줄의 창 컨트롤 오버레이 맞춤설정을 참고하세요.

창 컨트롤 오버레이를 사용하면 제목 표시줄에 콘텐츠를 렌더링할 수 있습니다.

창 관리

화면이 여러 개인 경우 사용자는 사용 가능한 공간을 모두 사용하고 싶어 합니다. 예를 들면 다음과 같습니다.

  • 멀티 윈도우 그래픽 편집기를 사용하면 다양한 편집 도구를 정확하게 배치된 창에 배치할 수 있습니다.
  • 가상 거래소는 여러 창에 시장 동향을 표시할 수 있으며, 이러한 창은 모두 전체 화면 모드로 볼 수 있습니다.
  • 슬라이드쇼 앱은 내부 기본 화면에 발표자 노트를 표시하고 외부 프로젝터에 프레젠테이션을 표시할 수 있습니다.

Window Management API를 사용하면 PWA에서 이 외에도 다양한 작업을 할 수 있습니다.

화면 세부정보 가져오는 중

Window Management API에 화면이 있는 객체를 연결된 화면의 변경 불가능한 배열로 반환하는 새 메서드 window.getScreenDetails()가 추가되었습니다. 현재 window.screen에 상응하는 ScreenDetails.currentScreen에서 액세스할 수 있는 라이브 객체도 있습니다.

screens 배열이 변경되면 반환된 객체는 screenschange 이벤트도 실행합니다. 개별 화면의 속성이 변경되는 경우에는 발생하지 않습니다. 개별 화면(window.screen 또는 screens 배열의 화면)에서는 속성이 변경될 때 change 이벤트를 실행합니다.

// Request an object with a screen objects
const screenDetails = await window.getScreenDetails();
screenDetails.screens[0].isPrimary;  // e.g. true
screenDetails.screens[0].isInternal;  // e.g. true
screenDetails.screens[0].label;  // e.g. 'Samsung Electric Company 28"'

// Access the live object corresponding to the current `window.screen`.
// The object is updated on cross-screen window placements or device changes.
screenDetails.currentScreen;
screenDetails.addEventListener('screenschange', function() {
 // NOTE: Does not fire on changes to attributes of individual screens.
  const screenCount = screenDetails.screens.length;
  const currentScreen screenDetails.currentScreen.id;
});

사용자 또는 운영체제가 PWA의 창을 한 화면에서 다른 화면으로 이동하면 화면 세부정보 객체에서도 currentscreenchange 이벤트가 실행됩니다.

화면 wake lock

주방에서 태블릿으로 레시피를 따라 하고 있다고 상상해 보세요. 재료 준비를 마쳤습니다. 손이 엉망진창이어서 기기를 다시 돌려 다음 단계를 읽어 봅니다. 큰일이에요! 화면이 검은색으로 바뀌었어요! Screen Wake Lock API를 사용하면 PWA에서 화면이 어두워지거나 절전 모드로 전환되거나 잠기지 않도록 할 수 있으므로 사용자가 걱정 없이 앱을 중지, 시작, 종료, 다시 시작할 수 있습니다.

// Request a screen wake lock
const wakeLock = await navigator.wakeLock.request();

// Listen for wake lock release
wakeLock.addEventListener('release', () => {
 console.log(`Screen Wake Lock released: ${wakeLock.released}`);
});
// Manually release the wake lock
wakeLock.release();

가상 키보드

휴대전화 및 태블릿과 같은 터치 기반 기기는 사용자가 PWA의 양식 요소에 포커스가 있을 때 입력할 수 있도록 가상 화면 키보드를 제공합니다.

VirtualKeyboard API 덕분에 이제 PWA는 다음을 비롯하여 navigator.virtualKeyboard 인터페이스를 사용하여 호환되는 플랫폼에서 키보드를 더 효과적으로 제어할 수 있습니다.

  • navigator.virtualKeyboard.show()navigator.virtualKeyboard.hide() 함수를 사용하여 가상 키보드를 표시하고 숨깁니다.
  • navigator.virtualKeyboard.overlaysContenttrue로 설정하여 가상 키보드를 직접 닫겠다고 브라우저에 알립니다.
  • navigator.virtualKeyboardgeometrychange 이벤트와 함께 키보드가 표시되고 사라지는 시점을 파악합니다.
  • virtualkeyboardpolicy HTML 속성으로 호스트 요소 수정 (contenteditable 사용) 시 가상 키보드 정책 설정 정책을 사용하면 가상 키보드를 auto 값을 사용하여 브라우저에서 자동으로 처리할지 아니면 manual 값을 사용하여 스크립트에서 처리할지 결정할 수 있습니다.
  • CSS 환경 변수를 사용하여 keyboard-inset-heightkeyboard-inset-top와 같은 가상 키보드 모양에 관한 정보를 가져옵니다.

VirtualKeyboard API로 전체 제어에서 이 API에 대해 자세히 알아보세요.

리소스