Skip to content

Commit 2922708

Browse files
author
seungwonme
committed
Implement new component structure in vanilla JS
1 parent 3b53330 commit 2922708

13 files changed

+247
-1
lines changed

Diff for: JavaScript/component/README.md

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Vanilla JavaScript로 웹 컴포넌트 만들기
2+
3+
## 1. State
4+
5+
1. `state`가 변경되면 `render` 함수가 호출된다.
6+
2. `state``setState` 함수를 통해서만 변경할 수 있다.
7+
8+
## Reference
9+
10+
- [Web Components](https://developer.mozilla.org/ko/docs/Web/Web_Components)
11+
- [Custom Elements](https://junilhwang.github.io/TIL/Javascript/Design/Vanilla-JS-Component/#_1-%E1%84%89%E1%85%A1%E1%86%BC%E1%84%90%E1%85%A2%E1%84%80%E1%85%AA%E1%86%AB%E1%84%85%E1%85%B5%E1%84%8B%E1%85%B4-%E1%84%90%E1%85%A1%E1%86%AB%E1%84%89%E1%85%A2%E1%86%BC)
12+

Diff for: JavaScript/component/index.html

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="ko">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>State</title>
7+
<link rel="stylesheet" href="./src/index.css">
8+
</head>
9+
<body>
10+
<dic id="app"></dic>
11+
<script src="./src/app.js" type="module"></script>
12+
</body>
13+
</html>

Diff for: JavaScript/component/src/app.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Items from "./components/Items.js";
2+
3+
class App {
4+
constructor() {
5+
const $app = document.querySelector("#app");
6+
new Items($app);
7+
}
8+
}
9+
10+
new App();

Diff for: JavaScript/component/src/components/Items.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import Component from "../core/Component.js";
2+
3+
export default class Items extends Component {
4+
setup() {
5+
this.state = { items: ["item1", "item2"] };
6+
}
7+
template() {
8+
const { items } = this.state;
9+
return `
10+
<ul>
11+
${items.map((item, key) => `
12+
<li>
13+
${item}
14+
<button class="deleteBtn" data-index="${key}">삭제</button>
15+
</li>
16+
`).join("")}
17+
</ul>
18+
<button class="addBtn">추가</button>
19+
`;
20+
}
21+
setEvent() {
22+
this.$target.querySelector(".addBtn").addEventListener("click", () => {
23+
const { items } = this.state;
24+
this.setState({ items: [...items, `item${items.length + 1}`] });
25+
});
26+
27+
this.$target.querySelectorAll(".deleteBtn").forEach((deleteBtn, index) => {
28+
deleteBtn.addEventListener("click", () => {
29+
const { items } = this.state;
30+
items.splice(index, 1);
31+
this.setState({ items });
32+
});
33+
});
34+
}
35+
}

Diff for: JavaScript/component/src/core/Component.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export default class Component {
2+
$target;
3+
state;
4+
constructor ($target) {
5+
this.$target = $target;
6+
this.setup();
7+
this.render();
8+
}
9+
setup () {};
10+
template () { return ''; }
11+
render () {
12+
this.$target.innerHTML = this.template();
13+
this.setEvent();
14+
}
15+
setEvent () {};
16+
setState (newState) {
17+
this.state = { ...this.state, ...newState };
18+
this.render();
19+
}
20+
}

Diff for: JavaScript/component/src/index.css

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/* http://meyerweb.com/eric/tools/css/reset/
2+
v2.0 | 20110126
3+
License: none (public domain)
4+
*/
5+
6+
html, body, div, span, applet, object, iframe,
7+
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
8+
a, abbr, acronym, address, big, cite, code,
9+
del, dfn, em, img, ins, kbd, q, s, samp,
10+
small, strike, strong, sub, sup, tt, var,
11+
b, u, i, center,
12+
dl, dt, dd, ol, ul, li,
13+
fieldset, form, label, legend,
14+
table, caption, tbody, tfoot, thead, tr, th, td,
15+
article, aside, canvas, details, embed,
16+
figure, figcaption, footer, header, hgroup,
17+
menu, nav, output, ruby, section, summary,
18+
time, mark, audio, video {
19+
margin: 0;
20+
padding: 0;
21+
border: 0;
22+
font-size: 100%;
23+
font: inherit;
24+
vertical-align: baseline;
25+
}
26+
/* HTML5 display-role reset for older browsers */
27+
article, aside, details, figcaption, figure,
28+
footer, header, hgroup, menu, nav, section {
29+
display: block;
30+
}
31+
body {
32+
line-height: 1;
33+
}
34+
ol, ul {
35+
list-style: none;
36+
}
37+
blockquote, q {
38+
quotes: none;
39+
}
40+
blockquote:before, blockquote:after,
41+
q:before, q:after {
42+
content: '';
43+
content: none;
44+
}
45+
table {
46+
border-collapse: collapse;
47+
border-spacing: 0;
48+
}
49+
50+
/* End of reset.css */
51+

Diff for: JavaScript/event/1-event.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
var btn = document.querySelector('button');
2+
btn.addEventListener('click', addItem);
3+
4+
function addItem() {
5+
console.log('Item added');
6+
}

Diff for: JavaScript/event/2-event-bubbling.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
var divs = document.querySelectorAll("div");
2+
3+
divs.forEach(function (div) {
4+
div.addEventListener("click", logEvent);
5+
});
6+
7+
function logEvent(event) {
8+
console.log(event.currentTarget.className);
9+
}

Diff for: JavaScript/event/3-event-capture.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
var divs = document.querySelectorAll("div");
2+
3+
divs.forEach(function (div) {
4+
div.addEventListener("click", logEvent, {
5+
capture: true,
6+
});
7+
});
8+
9+
function logEvent(event) {
10+
console.log(event.currentTarget.className);
11+
}

Diff for: JavaScript/event/4-stopPropagation.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
var divs = document.querySelectorAll("div");
2+
3+
divs.forEach(function (div) {
4+
div.addEventListener("click", logEvent, {
5+
// capture: true
6+
});
7+
});
8+
9+
function logEvent(event) {
10+
event.stopPropagation();
11+
console.log(event.currentTarget.className);
12+
}

Diff for: JavaScript/event/5-event-delegation.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* let inputs = document.querySelectorAll("input");
2+
inputs.forEach(function (input) {
3+
input.addEventListener("click", function (event) {
4+
alert("Clicked on " + event.currentTarget.id);
5+
});
6+
}); */
7+
8+
let itemLists = document.querySelector(".itemList");
9+
itemLists.addEventListener("click", function (event) {
10+
alert("Clicked on " + event.target.id);
11+
});
12+
13+
let li = document.createElement("li");
14+
let input = document.createElement("input");
15+
let label = document.createElement("label");
16+
let labelText = document.createTextNode("이벤트 위임 학습");
17+
18+
input.setAttribute("type", "checkbox");
19+
input.setAttribute("id", "item3");
20+
label.setAttribute("for", "item3");
21+
label.appendChild(labelText);
22+
li.appendChild(input);
23+
li.appendChild(label);
24+
itemLists.appendChild(li);

Diff for: JavaScript/event/index.html

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<!DOCTYPE html>
2+
<html lang="ko">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Event</title>
7+
<style>
8+
div {
9+
width: 100px;
10+
height: 100px;
11+
background-color: red;
12+
margin: 10px;
13+
}
14+
</style>
15+
</head>
16+
<body>
17+
<!-- <button>add one item</button>
18+
<script src="./1-event.js"></script> -->
19+
20+
<!-- <div class="one">
21+
<div class="two">
22+
<div class="three">
23+
</div>
24+
</div>
25+
</div> -->
26+
<!-- <script src="./2-event-bubbling.js"></script> -->
27+
<!-- <script src="./3-event-capture.js"></script> -->
28+
<!-- <script src="./4-stopPropagation.js"></script> -->
29+
30+
<h1>오늘의 할 일</h1>
31+
<ul class="itemList">
32+
<li>
33+
<input type="checkbox" id="item1">
34+
<label for="item1">이벤트 버블링 학습</label>
35+
</li>
36+
<li>
37+
<input type="checkbox" id="item2">
38+
<label for="item2">이벤트 캡쳐 학습</label>
39+
</li>
40+
</ul>
41+
<script src="./5-event-delegation.js"></script>
42+
</body>
43+
</html>

Diff for: readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
# Front-Practice
1+
# Web

0 commit comments

Comments
 (0)