728x90
반응형
자바스크립트로 라우터 구현
커스텀이벤트
자바스크립트를 사용하면 이벤트 핸들러를 할당할수 있으며
이벤트를 직접 만들수도 있습니다
1. 이벤트 생성
new CustomEvent("type",{detail:{전달객체}}) ===>이벤트객체 만듬
-type: 이벤트의 타입을 나타내는 문자열
-customEvent 두번째 인수엔 객체가 들어갈 수 있는데
detail이라는 프로퍼티를 추가해 커스텀 이벤트 관련 정보를
명시 정보를 이벤트에 전달할 수 있음
2. 이벤트 호출
dispatchEvent(커스텀 이벤트 객체)
이벤트 객체를 생성한 다음 dispatchEvent(이벤트객체)를 통해서
이벤트를 호출할 수 있음
ex)
new customEvent("customClick",
{detail: {message: "hi"}}
)
dispatchEvent(cuEvent)
dispatchEvent(new customEvent("customClick",{
detail: {message: "hihi"}
}))
3.이벤트 핸들링
window.addEventListener("customClick", (e)=>{
console.log(e.detail.message)
})
실습
customEvent.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="divElem">커스텀 이벤트 객체에 대해 배워봅시다.</div>
<script>
//const green = new CustomEvent('nameEvent', { 이벤트 객체를 따로만들어도되고
//detail: {name: "그린"}
//})
//const blue = new CustomEvent('nameEvent', {
//detail: {name: "블루"}
//})
//클릭이벤트지만 이름이 있을경우 알아서 해주는 이벤트
const red = new CustomEvent('nameEvent', {
detail: {name: "레드"} //detail말고는 안됨 detail 속성이 있음 얘는 무엇을 전달할수있음
})
window.addEventListener("nameEvent",(event) => {
console.log(event.detail.name)
console.log(event)
})
setTimeout(()=>{
window.dispatchEvent(red)
},1000)
window.dispatchEvent ( new CustomEvent('nameEvent', { //호출과 생성 둘다 같이 써도되구
detail: {name: "오렌지"}
}))
window.dispatchEvent ( new CustomEvent('nameEvent', {
detail: {name: "블루"}
}))
</script>
</body>
</html>
실습 2
customEvent.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn1">클릭1</button>
<button id="btn2">클릭2</button>
<script>
const customSample1 = new CustomEvent("consoleEvent",{
detail: {
message: "하하하하"
}
})
const customSample2 = new CustomEvent("consoleEvent",{
detail: {
message: "호호호호"
}
})
window.addEventListener("consoleEvent", (e)=>{
console.log(e.detail.message)
})
document.querySelector("#btn1").addEventListener("click", ()=>{
dispatchEvent(customSample1)
})
document.querySelector("#btn2").addEventListener("click", ()=>{
dispatchEvent(customSample2)
})
</script>
</body>
</html>
실습 3
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<nav class="navbar">
<a href="/">HOME</a>
<a href="/post/123">POST</a>
<a href="/shop">shop</a>
</nav>
<div id="app"></div>
<script src="./main.js"type="module"></script>
</body>
</html>
main.js
import App from "./src/app.js"
//초기html문서를 완전히 불러오고 분석했을때 발생
//html문서가 다 준비되면 실행해!!!!
window.addEventListener("DOMContentLoaded",()=>{
new App({target: document.querySelector("#app")})
})
src폴더에
app.js
import Router from "./router.js";
import { navigate } from "./utils/navigate.js";
export default function App({target}){
this.$container = target;
const init = () => {
document.querySelector(".navbar").addEventListener("click", (e)=>{
//이벤트제거
e.preventDefault();
const targetUrl = e.target.href.replace("http://127.0.0.1:5500","")
console.log(targetUrl)
navigate(targetUrl)
})
new Router(this.$container)
}
init();
}
src폴더에
router.js
import { routes } from "./contants/routerInfo.js";
export default function Router($container){
this.$container = $container;
//routes 배열을 돌며 path속성이 location.pathname과 일치하는 객체를 리턴
const findRoute = () => {
//{path: /^\/$/, element: () => console.log('메인페이지')},
const matchRoute = routes.find(route => route.path.test(location.pathname))
const TargetPage = matchRoute.element
new TargetPage(this.$container)
}
const init = () => {
window.addEventListener('historyChange', (e)=>{
const {to} = e.detail;
history.pushState(null, "", to)
findRoute()
})
window.addEventListener("popstate", ()=>{
findRoute() //얘가없으면 뒤로가기 눌렀을때 현재화면안됨
})
}
init()
findRoute()
}
contants폴더에
routerInfo.js
//정규표현식
// const re = /표현식작성/
// const re2 = new RegExp(표현식작성)
// path: /
// ^ -->문자의 시작 $ ----> 문자의 끝 ^/$
// /shop
import Main from "../pages/Main.js";
import Post from "../pages/Post.js";
import Shop from "../pages/Shop.js";
// /^\/post\/[\w]+$/ ---> /post//dd /post/d
export const routes = [
{path: /^\/$/, element: Main},
{path: /^\/post\/[\w]+$/, element: Post},
{path: /^\/shop$/, element: Shop},
]
utils폴더에
navigate.js
//navigate("abc") ---> 이벤트 생성 ----> 이벤트 발생
export const navigate = (to) => {
const historyChangeEvent = new CustomEvent("historyChange", {
detail: {to: to}
})
//이벤트 발생!!!
dispatchEvent(historyChangeEvent)
}
pages폴더에
Main.js
export default function Main($container){
this.$container = $container;
this.setState = () => {
this.render();
}
this.render = () => {
this.$container.innerHTML = `
<main class = "mainPage"> 메인페이지입니다. </main>
`
}
this.render()
}
pages폴더에
Post.js
export default function Post($container){
this.$container = $container;
this.setState = () => {
this.render();
}
this.render = () => {
this.$container.innerHTML = `
<main class = "postPage">
포스트페이지입니다.
</main>
`
}
this.render()
}
pages폴더에
Shop.js
export default function Shop($container){
this.$container = $container;
this.setState = () => {
this.render();
}
this.render = () => {
this.$container.innerHTML = `
<main class = "shopPage"> 샵페이지입니다. </main>
`
}
this.render()
}
style.css
#app {
text-align: center;
color: #2e3e50;
margin-top: 60px;
}
.navbar {
margin-top: 60PX;
text-align: center;
}
.navbar > a {
display: inline-block;
font-size:32px;
text-decoration: none;
border-radius: 18px;
background-color: #8040ff;
color: white;
padding: 5px 10px;
}
.mainPage {
background: #4a4b43;
padding: 50px 0;
color: white;
}
.postPage{
background: #40d2ff;
padding: 50px 0;
color: white
}
.shopPage {
background: #ff40cf;
padding: 50px 0;
color: white;
}
728x90
반응형
'프로그래머스' 카테고리의 다른 글
[프로그래머스]프로그래밍 언어 검색 (1) | 2023.03.03 |
---|
댓글