0.서론
기존의 웹은 페이지가 전환될 때마다 서버에서 화면을 렌더링한 후 브라우저에 바로 그려주는 서버 사이드 렌더링(SSR, Server-Side Rendering) 방식을 주로 사용하였다. 그러나, 페이지가 전환될 때마다 화면 전체를 다시 그리기 때문에 페이지가 로드되는 속도가 느리고 화면이 자주 깜빡거렸다.
그래서, 최근에는 브라우저에서 XHR을 통해 필요한 데이터만 서버에 요청한 후 데이터를 가지고 브라우저에서 화면을 그려주는 클라이언트 사이드 렌더링(CSR, Client-Side Redering) 방식을 많이 사용하고 있다. CSR은 요소를 생성할 때마다 동적으로 요소들을 생서한다. 그래서, 데이터만 입력받으면 요소를 생성할 수 있도록 필요한 모듈들을 미리 만들어 사용한다. 대표적인 예로 페이스북에서 만든 React 라이브러리가 있다.
이번 포스트에서는 Prototype을 이용한 모듈 패턴으로 Element를 동적으로 생성하는 모듈을 만들어 보도록 하겠다.
1. 프로젝트 준비
1-1. 프로젝트 구조
1) modules/MyListItem.js
: 리스트 아이템을 커스터마이징한 모듈.
2) index.html
: 기본 화면
2. HTML 작성
2-1.index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
<!DOCTYPE html>
<html lang="kr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Prototype을 이용한 모듈 패턴</title>
</head>
<body>
<div>
<ul id="list"></ul>
</div>
<script src="./modules/MyListItem.js"></script>
<script type="text/javascript">
// 리스트 요소 탐색
const list = document.getElementById("list");
// 리스트에 10개의 아이템을 추가
Array(10).fill(1).forEach(function(data, idx){
const key = data+idx;
// 아이템 요소 생성
const li = document.createElement("li");
// 아이템에 모듈을 적용
const instance = li.myListItem({
id: "item-"+key,
parent: list
});
// 리스트에 아이템 추가
list.appendChild(li);
});
</script>
</body>
</html>
|
cs |
1) [ 10 ln ] - 리스트 요소
2) [ 12 ln ] - 리스트 아이템 모듈을 로드
3) [ 18-32 ln ] - 리스트에 아이템 추가
: [ 25-28 ln ] - 생성한 리스트 아이템 모듈을 <li>태그에 적용.
3. Javascript 작성
3-1. modules/MyListItem.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
// 리스트 아이템 Object 생성
const MyListItem = function(config, el){
const self = this;
// 데이터를 저장할 변수
let datas = {}
// 현재 요소의 인스턴스를 가져올 수 있도록 설정
el.instance = self;
el.getInstance = function(){
return this.instance;
}
// Object에 현재 요소를 저장
self.el = el;
// 기본 함수를 설정
self.setConfig = function(k, v){ config[k] = v; }
self.getConfig = function(k){ return config[k]; }
self.setData = function(k, v){ datas[k] = v; }
self.getData = function(k){ return datas[k]; }
}
// Prototype을 이용한 모듈 패턴
MyListItem.prototype = (function(){
// 초기화 함수
function _init(self){
_initRender(self);
_initEvent(self);
}
// 렌더링 함수
function _initRender(self){
const id = self.getConfig("id");
const html = '<a style="color: red;">'+id+'</a>';
self.el.innerHTML = html;
self.el.id = self.getConfig("id");
}
// 이벤트 바인딩 함수
function _initEvent(self){
const a = self.el.querySelector("a");
a.addEventListener("click", function(event){
event.preventDefault();
alert(this.innerText);
});
}
// 각 함수를 Prototype에 적용
return {
init: function(){
_init(this);
},
setText: function(text){
const tag = self.el.querySelector("a");
tag.innerText = text;
},
setHTML: function(html){
this.el.innerHTML = html;
}
}
})();
// Element 객체에 myListItem 함수를 추가
Element.prototype.myListItem = function(setting){
// 기본 설정
const config = {
id: null,
parent: null,
url: null,
data: null
}
// 추가 설정
if( setting ){
Object.assign(config, setting);
}
// 현재 요소에 MyListItem 모듈을 적용
const module = new MyListItem(config, this);
// 초기화
module.init();
// 인스턴스를 반환
return module;
}
|
cs |
1) [ 2-22 ln ] - 모듈화할 Object를 생성
: [ 9-12 ln ] - 모듈이 적용된 Element에서 모듈의 기능을 사용하려면 instance가 필요함.
: [ 15-21 ln ] - 모듈의 정보를 접근하기 위한 변수 및 함수.
2) [ 25-64 ln ] - Prototype을 통해 Object에 클로저 함수들을 적용
: [ 27-30 ln ] - 초기화 함수'
: [ 33-39 ln ] - 렌더링 함수, 현재 요소에 'id'속성과 '<a>'태그를 추가.
: [ 42-49 ln ] - '<a>'태그에 클릭 이벤트를 적용.
3) [ 52-63 ln ] - 클로저 함수들을 호출하는 함수들을 반환
: [ 56-59 ln ] - 텍스트를 변경하는 함수.
: [ 60-62 ln ] - 아이템의 내부 요소를 HTML로 변경.
4) [ 67-89 ln ] - Element 객체에 myListItem 함수를 추가
: [ 82 ln ] - 옵션(config)과 함수를 호출한 요소(this)를 전달하여 모듈을 생성.
: [ 85 ln ] - 초기화 함수를 호출하여 Element를 렌더링.
4. 실행
4-1. index.html 실행
1) 실행하면 위와 같이 item-1 ~ item-10 까지 리스트가 추가됨.
2) 아이템을 클릭하면 alert가 실행됨.
4-2. 요소에 적용된 모듈 함수 사용
1
2
3
4
5
6
7
8
9
|
const item4 = document.getElementById("item-4");
const item4_inst = item4.getInstance();
console.log(item4_inst);
item4_inst.setText("아이템4 입니다.");
const item7 = document.getElementById("item-7");
const item7_inst = item7.getInstance();
console.log(item7_inst);
item7_inst.setHTML("<h1>아이템7입니다.</h1>");
|
cs |
1) [ 1 ln ] - <li id="item-4">요소를 탐색
2) [ 2 ln ] - <li>태그에 적용된 모듈을 가져오기
3) [ 3 ln ] - 모듈 정보 확인
4) [ 4 ln ] - 모듈의 함수를 사용하여 텍스트를 변경.
: [ 9 ln ] - innerHTML을 사용하기 때문에 click 이벤트가 실행되지 않음.
마치며
- Prototype을 이용해서 간단하게(?) 모듈 패턴을 만들어 보았다.
- Javascript에 익숙하지 않고 어렵게 느껴진다면, Prototype과 클로저를 먼저 선행학습하는 것을 추천한다.
'Font-end > Javascript' 카테고리의 다른 글
[Context Menu] 나만의 컨텍스트 메뉴 만들기 (1) | 2020.05.29 |
---|---|
[Redux] 무작정 시작하기 (1) - Redux란? (0) | 2020.04.23 |
[공적마스크API] 공적 마스크 판매 정보 조회 (2) | 2020.03.18 |
[그림판] HTML, CSS, JS로 그림판 만들기 (1) | 2020.03.03 |
[Drag&Drop] 드래그 앤 드롭으로 Element 움직이기 (0) | 2020.03.02 |
댓글