이번 시간에는 모달창을 만들어 보겠습니다.
모달창은 보통 배경은 어둡게 되고, 팝업 레이어가 뜨는 형태로 많이 사용되고 있습니다.
모달창을 만들기 위해서는 모달창에 어떤기능을 넣을지 기능정의를 해야 합니다.
- 보여주기
- 감추기
- 배경 어둡게 하는 레이어 생성
- 가운데 보여주기
간단하게 기능정의를 해봤는데, 이정도 기능을 가진 모달창을 어떻게 만드는지 알아보도록 하겠습니다.
먼저 HTML과 CSS를 정의를 합니다.
HTML
1
2
3
4
5
6
7
8
9
10
| <!-- 모달 창을 여는 버튼 -->
<button id="button">Open Modal</button>
<!-- 모달창 -->
<div id="modal">
<h3>Test Modal</h3>
<p>이 창은 모달창입니다.</p>
<button id="confirm_button">확인</button>
<button class="js_close">닫기</button>
</div> |
CSS
1
| #modal {display:none;background-color:#FFFFFF;position:absolute;top:300px;left:200px;padding:10px;border:2px solid #E2E2E2;z-Index:9999} |
버튼이 하나가 있고, 감춰진 레이어(모달창)가 있습니다.
버튼을 누르면 감춰진 레이어가 모달창으로 나타나게 되고, 확인 버튼이나 닫기 버튼을 누른다는 것이 예상되는 HTML 입니다.
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| <!-- 스크립트 영역 -->
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
<script type="text/javascript" src="Example.Modal.js"></script>
<script type="text/javascript">
// 모달창 인스턴트 생성
var myModal = new Example.Modal({
id: "modal" // 모달창 아이디 지정
});
// 모달 창 여는 버튼에 이벤트 걸기
$("#button").click(function() {
myModal.show(); // 모달창 보여주기
});
// 모달 창 안에 있는 확인 버튼에 이벤트 걸기
$("#confirm_button").click(function() {
alert("나는 모달창이다.");
myModal.hide(); // 모달창 감추기
});
</script> |
자바스크립트를 살펴 보면, 3가지 액션을 합니다.
- 모달창 인스턴트 생성
- 모달 창 여는 버튼에 이벤트 걸기
- 모달 창 안에 있는 확인 버튼에 이벤트 걸기
Example.Modal.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
| if(typeof(Example) == "undefined") var Example = {};
(function($){
Example.Modal = function() {
this.initialize.apply(this,arguments);
}
Example.Modal.prototype = {
initialize : function(hash) {
var obj = this;
// 멤버변수 정의
this.hash = this.getHashData(hash);
this.width = 0; // 콘텐츠 레이어 너비
this.height = 0; // 콘텐츠 레이어 높이
this.c_width = 0; // body 화면 너비
this.c_height = 0; // body 화면 높이
this.s_width = 0; // body 전체 너비
this.s_height = 0; // body 전체 높이
// 콘텐츠 레이어 사이즈 구하기(멤버변수에 저장)
this.getLayerSize();
// body 사이즈 구하기(멤버변수에 저장)
this.getBodySize();
// 추가 엘리먼트 생성
this.addElement();
// 마우스, 키 이벤트 정의
this.addEvent();
},
// Hash 변수정의
getHashData : function(hash) {
if(typeof(hash.id) == "undefined") hash.id = "modal"; // 개체 아이디
if(typeof(hash.is_slide) == "undefined") hash.is_slide = 0; // 슬라이딩 여부
return hash;
},
// 추가 엘리먼트 생성 - JS에서 추가해 주어야 할 HTML 작성합니다.
addElement : function() {
// 배경 레이어 HTML 받아오기
var html = this.addOverlay();
// 배경레이어 HTML을 콘텐츠레이어 앞에 추가
$("#"+this.hash.id).before(html);
},
// 마우스, 키 이벤트 정의
addEvent : function() {
var obj = this;
// 닫기 버튼 클릭 이벤트 정의
$("#"+this.hash.id+" .js_close").click(function() {
// 모달창 감추기(여기서 obj는 Example.Modal 인스턴트 자체를 의미)
obj.hide();
});
},
/* 주요기능 */
// 모달창 보여주기
show : function() {
// 가운데로 이동
this.moveCenter();
// 배경레이어 적용
this.applyOverlay();
// 콘텐츠 레이어 보여주기
$("#"+this.hash.id).show();
// 배경 레이어 보여주기
$("#"+this.hash.id+"_overlay").show();
},
// 모달창 감추기
hide : function() {
$("#"+this.hash.id).hide(); // 콘텐츠 레이어 감추기
$("#"+this.hash.id+"_overlay").hide(); // 배경 레이어 감추기
},
/* 부가 기능 */
// 콘텐츠 레이어의 너비와 높이를 구해서 멤버변수에 정의
getLayerSize : function() {
this.width = $("#"+this.hash.id).outerWidth();
this.height = $("#"+this.hash.id).outerHeight();
},
// body 사이즈 구해서 멤버변수에 정의
getBodySize : function() {
this.c_width = document.documentElement.clientWidth;
this.c_height = document.documentElement.clientHeight;
this.s_width = document.documentElement.scrollWidth;
this.s_height = document.documentElement.scrollHeight;
},
// 배경 레이어 HTML 생성
addOverlay : function() {
var html = "";
html += "<div id='"+this.hash.id+"_overlay' style='display:none;width:100%;position:absolute;top:0px;left:0px;opacity:0.5;background-color:#000000;z-Index:999'></div>";
return html;
},
// 콘텐츠 레이어를 가운데로 이동(top, left 조절해 줌)
moveCenter : function() {
// left 좌표 구하기
var left = Math.floor((this.c_width-this.width)/2);
// top 좌표 구하기
var res_height; // 콘텐츠를 화면상의 가운데로 두었을 때의 높이
if(this.c_height < this.height) { // 화면 높이 < 콘텐츠 레이어 높이
res_height = 0;
} else { // 화면 높기 >= 콘텐츠 레이어 높이
res_height = Math.floor((this.c_height-this.height)/2); // 차이를 빼서 2로 나눔. 그리고 내림.
}
var top = res_height+$(document).scrollTop(); // 화면상의 높이에 스크롤높이를 더한 절대좌표를 top에 저장
// css의 top,left 조정
$("#"+this.hash.id).css("top",top);
$("#"+this.hash.id).css("left",left);
},
// 배경 레이어 적용
applyOverlay : function() {
// body 사이즈 구하기(멤버변수에 저장)
this.getBodySize();
// 배경 레이어에 width, height css 값 조정
$("#"+this.hash.id+"_overlay").css("width",this.s_width);
$("#"+this.hash.id+"_overlay").css("height",this.s_height);
}
}
})(jQuery); |
소스가 긴데 크게 보면(메소드 단위) 간단한 소스입니다.
아래 화면을 보면 이클립스가 있고, 우측에 아웃라인 뷰라고 해서, JS 클래스의 구조를 볼 수 있는 편리한 뷰가 생깁니다.
이클립스의 장점이죠.

어쨌든 이 메소드들이 어떤 일을 하는지 알아보도록 하겠습니다.
initialize
인스턴트를 생성했을 때 초기화를 시켜주는 생성자입니다. 인스턴트 생성되었을 때 하는 모든일은 여기서 정의하게 됩니다.
getLayerSize(), getBodySize(), addElement(), addEvent() 메소드를 실행시켜주게 됩니다. 이 메소드에서는 아래부분에서 알아보도록 하겠습니다.
getHashData
다음과 같은 부분이 있는데, getHashData 메소드를 실행시키고 그 반환값을 멤버변수인 this.hash에 집어넣는다는 의미입니다.
이 메소드는 자바스크립트 인스턴트의 기본(default)값을 정의하는 역할을 합니다.
13
| this.hash = this.getHashData(hash); |
addElement
추가 엘리먼트를 생성합니다. 모달창 div 나 버튼 같은 요소들은 Javascript로 처리되기 전에 있어도 상관 없지만, 백그라운드 레이어 같은 경우는 모달창이 뜰때만 필요한 부분일 수도 있기 때문에 동적으로 생성되는게 더 효율적이라고 생각이 됩니다.
addEvent
모듈에 관련된 요소들에 이벤트를 걸어줍니다.
여기서는 모달창 모듈의 닫기 버튼에 클릭이벤트를 걸었습니다.
show
가장 중요한 보여주기 기능입니다.
콘텐츠 레이어를 가운데로 옮기고, 배경레이어 사이즈 조정 후 콘텐츠와 배경레이어를 보여줍니다.
hide
감추는 기능입니다.
모달창과 배경레이어를 감추는 내용입니다.
getLayerSize
콘텐츠 레이어의 너비와 높이를 구하는 메소드입니다.
가운데 정렬하기 위해서 필요한 수치이기 때문에 이 메소드를 따로 두게 되었습니다.
getBodySize
body의 너비와 높이를 구하는 메소드입니다.
이 메소드 역시 가운데 정렬을 하기 위해 필요합니다.
addOverlay
단순히 배경 레이어를 생성하고, css를 in-line으로 정의되어서 독립적으로 쓸 수 있습니다.
moveCenter
위 메소드를 실행시켜 구한 수치들을 이용해서 계산을 하는 메소드입니다.
마지막에는 css의 top, left 의 수치를 변화시켜서 가운데 정렬을 하게됩니다.
applyOverlay
배경 레이어의 사이즈를 body의 사이즈에 따라서 변화를 시킵니다.
이 메소드는 resize를 할 때 body의 사이즈가 달라졌을 경우 실행시키도록 하면 항상 body를 덮는 배경레이어를 만들 수 있습니다.