[DAY-14] VanillaJS를 통한 JS 기본 역량 강화(6)
😉 헷갈렸던 & 몰랐던 부분들만 정리하는 나만의 TIL
😯 모든 강의 내용은 적지 않아요!
오늘의 소감은?
로토님의 맥북 고양이에 시선이 자꾸 뺏겨서 혼났습니다.
라우트 함수는 구글링을 통해서만 복붙해서 사용했는데
해당 함수와, 세션 스토리지 history API에 대해 원리를 자세히 파악할 수 있어서 너무 유익한 시간이었습니다.
모두 로토님의 귀여운 맥북 고양이를 봐주세요 😸 ㅠㅠ
[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>";
}
};
😁 적용 완료
[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()
은 상위 엘리먼트들로의 이벤트 전파를 중단시킴을 알 수 있습니다.
댓글남기기