[모듈] Prototype을 이용한 모듈 패턴으로 Element 모듈 만들기

[모듈] Prototype을 이용한 모듈 패턴으로 Element 모듈 만들기

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 > Colored by Color Scripter cs

1) [ 10 ln ] - 리스트 요소

2) [ 12 ln ] - 리스트 아이템 모듈을 로드

3) [ 18-32 ln ] - 리스트에 아이템 추가

: [ 25-28 ln ] - 생성한 리스트 아이템 모듈을 태그에 적용.

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 = '' + id + '' ; 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; } Colored by Color Scripter 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'속성과 ''태그를 추가.

: [ 42-49 ln ] - ''태그에 클릭 이벤트를 적용.

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( "아이템7입니다." ); cs

1) [ 1 ln ] - 요소를 탐색

2) [ 2 ln ] - 태그에 적용된 모듈을 가져오기

3) [ 3 ln ] - 모듈 정보 확인

4) [ 4 ln ] - 모듈의 함수를 사용하여 텍스트를 변경.

: [ 9 ln ] - innerHTML을 사용하기 때문에 click 이벤트가 실행되지 않음.

마치며

- Prototype을 이용해서 간단하게(?) 모듈 패턴을 만들어 보았다.

- Javascript에 익숙하지 않고 어렵게 느껴진다면, Prototype과 클로저를 먼저 선행학습하는 것을 추천한다.

from http://heodolf.tistory.com/108 by ccl(A) rewrite - 2020-03-19 18:20:24

댓글

이 블로그의 인기 게시물

단위 테스트 환경 구축

Coupang CS Systems 채용 정보: Front-end 개발자를 찾습니다!

스토리북에서 스토리를 작성하는 방법