Chrome 105의 NavigationEvent 변경사항

Joe Medley
Joe Medley

Chrome 105에서는 실제로 문제가 있는 것으로 입증된 메서드를 개선하기 위해 Navigation API의 NavigateEvent에 두 가지 새로운 메서드 (102에서 도입)가 도입되었습니다. 개발자가 탐색 후 상태를 제어할 수 있는 intercept()가 사용하기 어려운 transitionWhile()를 대체합니다. URL에 지정된 앵커로 스크롤되는 scroll() 메서드는 일부 탐색 유형에서는 작동하지 않는 restoreScroll()를 대체합니다.

이 도움말에서는 두 가지 문제 모두와 새 방법으로 이러한 문제를 해결하는 방법에 대해 설명합니다.

Chrome 102의 Navigation API와 함께 도입된 NavigateEvent.trasitionWhile() 메서드는 단일 페이지 앱에서 클라이언트 측 전환을 위해 탐색을 가로챕니다. 첫 번째 인수는 브라우저와 웹 애플리케이션의 다른 부분에 완료되었음을 알리는 프로미스입니다.

이것은 실제로 제대로 작동하지 않았습니다. 다음과 같은 일반적인 코딩 패턴을 고려해 보세요.

event.transitionWhile((async () => {
  doSyncStuff();
  await doAsyncStuff();
})());

이는 아래 코드와 기능적으로 동일합니다. 이렇게 하면 API에서 개발자가 탐색을 가로채려고 한다는 것을 인식하기 전에 탐색의 일부가 실행됩니다.

doSyncStuff();
event.transitionWhile((async () => {
  await doAsyncStuff();
})());

이런 식으로 앱이 엉망이 될 수 있는 한 가지 예는 스크롤 복원 로직입니다. 이 로직에서는 DOM 변경 전이 아닌 이후 스크롤 위치를 캡처합니다.

변경된 내용

transitionWhile()를 대체하기 위해 현재 사양에 NavigateEvent.intercept()가 도입됩니다. 새 메서드는 transitionWhile()에서 지원하는 focusResetscrollRestoration 속성 외에도 핸들러를 사용합니다. 새 핸들러는 탐색 커밋이 실행된 후 항상 실행되고 스크롤 위치 등이 캡처된 후에 실행되므로 transitionWhile() 관련 문제를 피할 수 있습니다.

transitionWhile() 메서드는 계속 사용할 수 있지만 지원 중단되었으며 Chrome 108에서 삭제될 예정입니다.

intercept() 사용

NavigateEvent.intercept()에는 transitionWhile()와 동일한 제한사항이 있습니다. 모든 탐색 이벤트에서 호출할 수 없기 때문입니다. 교차 출처 탐색은 가로챌 수 없으며 문서 간 순회도 가로챌 수 없습니다. 이렇게 하면 "SecurityError" 유형의 DOMException이 발생합니다.

intercept()를 사용하려면 호출할 때 맞춤 핸들러를 전달하기만 하면 됩니다.

navigation.addEventListener("navigate", event => {
  event.intercept({
    async handler() {
      doSyncStuff();
      await doAsyncStuff();
    }
  });
});

페이지 상단에서 앵커로 이동하는 것과 같은 탐색 (/a에서 /a#id로 이동)은 단일 페이지 앱에서도 브라우저에서 완전히 처리됩니다. 하지만 여러 페이지 앱에서 간단한 앵커인 다른 '페이지' (/a~/b#id)로 이동하는 것은 단일 페이지 앱에서 더 복잡합니다. 앱은 NavigateEvent.transitionWhile()를 사용하여 /b#id로 이동하는 탐색을 가로채고 NavigateEvent.restoreScroll()를 호출하여 앵커를 뷰로 가져와야 합니다. 위에서 언급했듯이 현재는 이렇게 하기가 어렵습니다.

변경된 내용

단일 페이지 앱에서는 이제 브라우저가 앵커로 스크롤하는 것을 처리할지 아니면 코드에서 처리할지를 제어할 수 있습니다.

Scroll() 사용

기본적으로 브라우저는 가로채기 처리기가 완료되면 스크롤을 자동으로 처리하려고 시도합니다. 스크롤을 직접 처리하려면 scroll"manual"로 설정하고 브라우저에서 스크롤 위치를 설정하려고 할 때 NavigateEvent.scroll()를 호출합니다.

navigation.addEventListener("manual", event => {
  scroll: "manual",
  event.intercept({
    async handler() {
      doSyncStuff();
      // Handle scrolling earlier than by default:
      event.scroll();
      await doAsyncStuff();
    }
  });
});

restoreScroll() 메서드는 계속 사용할 수 있지만 지원 중단되었으며 Chrome 108에서 삭제될 예정입니다.

결론

Navigation API에 관한 문서를 곧 업데이트할 수 있도록 노력하겠습니다. 그때까지는 이 API의 사양에 웹 개발자를 위한 자세한 정보를 확인해 보세요.

사진: Tim Gouw, Unsplash