notion-040

😉 헷갈렸던 & 몰랐던 부분들만 정리하는 나만의 TIL
😯 모든 강의 내용은 적지 않아요!

오늘의 소감은?
로토님의 맥북 고양이에 시선이 자꾸 뺏겨서 혼났습니다.

라우트 함수는 구글링을 통해서만 복붙해서 사용했는데
해당 함수와, 세션 스토리지 history API에 대해 원리를 자세히 파악할 수 있어서 너무 유익한 시간이었습니다.


UntitledUntitled 1

모두 로토님의 귀여운 맥북 고양이를 봐주세요 😸 ㅠㅠ




[1] history API

브라우저에서 페이지 로딩을 하면 세션 히스토리를 가지게 되는데,

이 세션 히스토리는 페이지를 이동할때마다 쌓이게 되며 따라서 앞으로 가기 뒤로 가기가 가능합니다.

따라서 화면 이동을 일으키지 않고도 브라우저의 url을 바꿀 수 있습니다.


history API를 사용하면 hashbang으로 했던 url을 바꿔줄 수 있습니다.

일반 url 형식을 따르기 때문에 queryString도 자유롭게 붙일 수 있습니다.

  • / → HomePage
  • /list → ListPage


또한 history API로 url을 변경한 후 새로고침하면, 변경된 url의 실제 파일을 찾으려 하기 때문에 404 에러가 출력됩니다.

따라서 404 에러가 났을 경우, root의 index.html로 요청을 돌려주는 처리가 필요합니다.


* 예시
/product/1 경로로 이동한 후 새로고침하면, 해당 위치의 index.html을 찾습니다.
따라서 에러가 출력됩니다.


[1-1] 사용 방법

[1] history.pushState(state, title, url)

  • 세션 히스토리에 새 url을 쌓습니다.
  • state : history.state에서 꺼내쓸 수 있는 값
  • title: 변경될 페이지의 타이틀을 가리키는 값 같지만, 대부분의 브라우저에서 지원하지 않으므로 빈 string을 넣으면 됩니다.
  • url : 세션 히스토리에 새로 넣을 url입니다. 해당 url이 변경된다고 해서 화면이 리로드되거나 하지 않습니다.


[2] history.replaceState(state, title, url)

  • 세션 히스토리에 새 url 상태를 쌓지 않고 현재 url을 대체합니다.
  • state : history.state에서 꺼내쓸 수 있는 값
  • title: 변경될 페이지의 타이틀을 가리키는 값 같지만, 대부분의 브라우저에서 지원하지 않으므로 빈 string을 넣으면 됩니다.
  • url : 세션 히스토리에 새로 넣을 url입니다. 해당 url이 변경된다고 해서 화면이 리로드되거나 하지 않습니다.
  • 로그인페이지 같이 뒤로가기가 불가한 페이지에서 사용합니다.




[2] url routing 처리

history API에서 중요한 포인트

  • url path별로 어떠한 페이지를 나타내는지 추상화된 각 페이지 컴포넌트를 정의해야 합니다.
  • path에 따라 페이지 컴포넌트가 렌더링되야 합니다. → route 함수
  • url이 변경되는 경우, route 함수가 호출되어야 합니다.


[2-1] 실습

주의할 부분이 있습니다.

모듈을 불러오는 과정에서 상대 경로로 작성하면

해당 상대 경로를 기준으로 다른 path가 불러와지므로 꼭 절대 경로로 작성합니다.

// index.html 일부
<body>
  <div id="app"></div>
  <script src="/0406/src/main.js" type="module"></script>
</body>

js 파일 import 하는 부분은 상대 경로로 작성해도 괜찮습니다.


저는 루트 페이지가 /0406/의 경로를 갖고 있기 때문에, home Page의 경로를 다르게 설정했습니다.

// App.js route()

this.route = () => {
  const { pathname } = location;

  console.log(pathname);

  $target.innerHTML = "";
  if (pathname === "/0406/") {
    // 홈페이지
    homePage.render();
    console.log(pathname);
  } else if (pathname.indexOf("/products") > -1) {
    //ProductPage
    const [, , productId] = pathname.split("/");

    productPage.setState({
      productId,
    });
  } else {
    $target.innerHTML = "<h1>404 not found!</h1>";
  }
};

Untitled 2

Untitled 3

Untitled 4

😁 적용 완료




[3] e.preventDefault()

history API 실습 진행중 또 만난 e.preventDefault()

// ...
window.addEventListener('click', e=> {
  if (e.target.className === 'LinkItem') {
    e.preventDefault(); // 넌 정확히 무엇이냐

    const { href } = e.target;
// ...

history API를 제외하고도 많은 이벤트에서 만났던 e.preventDefault에 대해서 알아보고자 합니다.


[3-1] e.preventDefault()

html에서 a태그나 submit태그는 고유의 동작이 있습니다.

e.preventDefault()는 해당 동작을 중단시킵니다.

$("a").click(function (e) {
  e.preventDefault();
  alert("e.preventDefault()");
});

해당 코드로 동작하는 html의 경우,

a 태그의 href 속성이 중단되고 e.preventDefault()를 띄우는 것을 알 수 있습니다.


[3-2] e.stopPropagation()

아래의 코드로 이루어진 html의 경우,

단지 last-el을 클릭해도 모두 click이벤트가 등록되어 있으면

부모 엘리먼트에도 이벤트가 전파됨을 알 수 있습니다.

<div class="first">
  <ul class="second">
    <li class="third">
      <div class="last-el">event</div>
    </li>
  </ul>
</div>

e.stopPropagation()의 경우 이벤트가 상위 엘리먼트에 전달되지 않게 해줍니다.

$(".last-el").click(function (e) {
  e.stopPropagation(); // 상위 엘리먼트로의 이벤트 전파를 중단시킵니다.
  alert("last-el");
});
$(".third-cover").click(function () {
  alert("third-cover");
});
$(".second-cover").click(function () {
  alert("second-cover");
});
$(".first-cover").click(function () {
  alert("first-cover");
});



따라서 e.preventDefault()고유 동작을 중단시키며

e.stopPropagation()상위 엘리먼트들로의 이벤트 전파를 중단시킴을 알 수 있습니다.





출처

프로그래머스

https://pa-pico.tistory.com/20

댓글남기기