Chrome 105의 NavigationEvent 변경사항

Joe Medley
Joe Medley

Chrome 105에서는 실제로 문제가 있는 메서드를 개선하기 위해 Navigation API (102에서 도입됨)의 NavigateEvent에 두 가지 새로운 메서드를 도입합니다. 개발자가 탐색 후 상태를 제어할 수 있는 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의 사양에서 웹 개발자를 위한 많은 정보를 확인하세요.

사진: Unsplash팀 고우