DOM 내비게이션에서 DOMContentLoaded를 우회하는 방법?

DOMContentLoaded에서 실행되는 JS 함수가 있습니다: document.addEventListener(“DOMContentLoaded”, OURFUNCTION).

브라우저를 새로고침하면 잘 작동하지만, 사이트 내 페이지를 이동할 때는 절대 표시되지 않습니다. 이는 Discourse가 DOM을 한 번만 로드하고, 그 이후는 SPA처럼 클라이언트 사이드 네비게이션으로 처리하기 때문이라고 추정합니다. 그렇다면 Discourse 자체에서 네비게이션 변경 시 함수를 실행하려면 어떻게 해야 할까요? 예전에는 플러그인 API를 통해 이를 쉽게 할 수 있는 방법이 있었지만, 해당 API는 비추천(deprecated) 상태이며 더 이상 어떤 컴포넌트에서도 사용되고 있지 않습니다. 이걸 여전히 쉽게 할 수 있는 간단한 방법이 있을까요? 아니면 네비게이션 변경 시 일부 JavaScript를 실행하기 위해 컴포넌트를 통째로 만들어야 하나요? 감사합니다.

안녕하세요,

페이지 로드 시 발생하는 이벤트를 찾고 계신다면 api.onPageChange를 사용할 수 있습니다.

api.onPageChange((url, title) => {
   console.log('the page changed to: ' + url + ' and title ' + title);
});

다른 것을 찾고 계신다면, 달성하려는 내용을 좀 더 자세히 설명해 주시겠습니까? 그러면 더 정확한 답변을 드릴 수 있을 것입니다.

참고로, 도움이 될 수 있는 문서가 많이 준비되어 있습니다: Developer Guides - Discourse Meta.

음 … DOM 콘텐츠가 로드되었음을 보장하는지 확실하지 않아요. 라우트 변경 시점에 발화되는 것 같고, 이는 훨씬 이른 시점입니다.

DOM 로딩이 중요하다면, 컴포넌트를 플러그인 아웃렛에 연결하고 didInsert 수정자에서 발화하는 것을 고려해야 합니다.

라우트 변경만 중요하다면, onPageChange가 해결해 줄 수 있습니다. :+1:

말씀이 맞을 수도 있겠네요! :thinking:

onPageChange는 다음 runloop에서 호출되므로, 대부분의 상황에서는 DOMContentLoaded 이후에 호출될 것으로 생각하지만, 이것이 보장된다고 단정할 수는 없습니다.

onPageChange에 의존하여 DOM 요소 관련 작업을 직접 수행하는 용례를 볼 수 있습니다. 참고로 routeDidChange 이벤트는 어디서 발화되는 건가요? (수정: ember에서 발화됩니다: ObjectProxy | 7.2.0 | Ember API Documentation)

didInsert 수정자에 대해서는 동의합니다. 정말 깔끔하네요!

감사합니다. 문서를 꼼꼼히 읽어봤고, 제 코멘트와 디스커스(Discourse) 멤버의 후속 답변에 따르면 플러그인 API는 레거시이며 곧 비추천(deprecated) 처리될 예정이라고 합니다. 따라서 현재는 동작할 수 있지만, 향후 업데이트에서 깨질 가능성이 높다고 생각합니다. 그래서 더 나은 솔루션을 찾고 있습니다. 이 정도 기능을 위해 글리머(Glimmer) 컴포넌트를 만드는 것은 과한 것 같아, 다른 이벤트를 활용할 수 있지 않을까 해서 문의드립니다.

그것이 정확하지 않다고 생각합니다.

이 링크는 지난주에 업데이트되었습니다.

비추천(deprecated)된 항목은 다음과 같습니다:

  • 위젯 API
  • Raw 템플릿
  • 일반적인 템플릿 오버라이딩

정리해 주셔서 감사합니다! 그래서 위젯 API만 해당되는 거군요. 그럼 먼저 위에 제시된 API 제안들을 시도해 보겠습니다.

이건 오히려 축복이죠 :sweat_smile:, Glimmer은 개발자에게 훨씬 더 친화적이니까요

참고로, api.OnPageChange로 테스트해 봤는데 정상적으로 작동합니다. 아직까지 OnPageChange를 호출할 때 DOM 콘텐츠가 사용 불가능한 경우는 한 번도 겪어 본 적이 없기 때문에, DomContentLoaded 이후에 발화되는 것으로 보입니다. 다만 100% 확신은 못 하겠습니다. 이 문제에 대해 도움을 주셔서 감사합니다.

좋습니다. 다만 타이밍이 보장되지는 않는다는 점에 유의하세요. 하지만 사용 사례에 맞게 작동하게 되어 기쁩니다!

이것이 무엇을 의미하는지 좀 더 자세히 설명해 주실 수 있을까요? didInsert 수정자란 무엇인가요? 저는 decorateCookedElement에서 발동시키고 있습니다. 감사합니다.

로버트가 지적했듯이, 문서가 가장 좋은 방법입니다. 레포지토리에서도 수많은 예제를 확인할 수 있습니다: Code search results · GitHub

아, 알겠습니다. 그러면 이건 ember 기능이고 discourse와는 관련이 없군요? 코드에서 실제로 "discourse"와 관련이 있는 부분은 pluginoutlet뿐이겠네요?

네, Glimmer 표준의 일부입니다.

pluginOutlets는 다른 Components를 마운트하도록 설계된 특별한 Components입니다: