앞에서 팝업을 이 부분까지 구현했었다. 함수의 매개 변수를 이용하여 팝업창을 2개로 만들어보자.
우선 매개 변수를 사용하지 않는다고 하면 어떻게 구현할까?
html
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!--jQuery사용을 위한 코드-->
<!--팝업1-->
<div class="popup-1 popup">
<div class="popup__content">
<!--부모 .popup클래스는 배경색을 흐리게 만드느데 사용하고 popup__content를 만들어
새로 팝업창을 만든다.-->
<!--팝업 헤더-->
<div class="popup__head">
<div class="popup__btn-close"></div>
</div>
<!--팝업 내용-->
<div class="popup__body">
<div class="con">
Lorem ...
</div>
</div>
</div>
</div>
<!-- 팝업2 -->
<div class="popup-2 popup">
<div class="popup__content">
<div class="popup__head">
<div class="popup__btn-close"></div>
</div>
<div class="popup__body">
<div class="con">
팝업2
</div>
</div>
</div>
</div>
<section class="section-1">
<div class="con">
<!--팝업 생성 버튼-->
<button class="btn-popup-1">팝업 1</button>
Lorem ipsum...
</div>
</section>
<section class="section-1">
<div class="con">
<button class="btn-popup-1">팝업 1</button>
<button class="btn-popup-2">팝업 2</button>
Lorem...
</div>
</section>
css
/*노말라이즈*/
body, ul, li {
margin:0;
padding:0;
list-style:none;
}
a {
color:inherit;
text-decoration:none;
}
/*컨텐츠 너비만들고 가운데로 옮겨 양 옆 여백만들기*/
.con {
margin-left:auto;
margin-right:auto;
}
.con {
max-width:1200px;
}
.popup {
position:fixed;
top:0;
left:0;
right:0;
bottom:0;
background-color:rgba(0,0,0,0.5);
/*웹을 가득 채우고 배경색을 흐린 검정색으로 만든다.*/
align-items:center;
justify-content:center;
display:flex;
/*display를 flex로 만들어 팝업창(.popup__content)를 정가운데로 옮긴다.*/
opacity:0;
visibility:hidden;
/*불투명도를 0으로 만들어 평소에 보이지 않게 만들고 visivility로 숨긴다. .active클래스가 추가되면 나타나게 한다.*/
transition: opacity .3s, visibility .3s;
/*opacity와 visibility에 재생시간을 부여한다.*/
}
.popup.active {
opacity:1;
visibility:visible;
/*팝업을 다시 나타나게 하는 클래스를 만든다.*/
}
.popup__content {
min-width:200px;
min-height:200px;
/*최소 너비, 높이 지정*/
background-color:white;
border:2px solid black;
transform:translateY(-100%);
/*평소에는 팝업창이 위에 있게 만들고 .active클래스 추가로 가운데 오게 만든다.*/
transition: transform .3s;
/*transform에 재생시간을 부여한다.*/
}
/*.popup과 .active클래스를 모두 가지고 있는 태그의 후손이면서
.popup__content를 가지고 있는 태그에게 적용하는 속성*/
/*원래는 .popup이 .active클래스를 가지고 있지 않으므로 이 속성이 활성화
되지 않지만 JS를 이용해 .popup이 .active클래스를 갖는 순간 활성화된다.*/
/*단순히 .active클래스를 라이브러리처럼 사용하는 것이 아니라 관련된 클래스를 만들어
클래스를 추가하는 것만으로 여러 css속성이 추가되도록 구현한 것!!*/
.popup.active .popup__content {
transform:translateY(0);
/*다시 원래 자리로 오게하는 클래스를 만든다.*/
}
.popup__head {
padding:10px;
}
.popup__btn-close {
width:30px;
height:30px;
/*X표를 만들기위해 네모 틀을 만든다.*/
margin-left:auto;
/*.popup__head의 오른쪽에 붙인다.*/
position:relative;
/*before, after태그를 absolute로 하고 이 태그를 유령의 집으로 만든다.*/
cursor:pointer;
transition:transform 0.3s;
/*transform(rotate)에 재생시간을 부여한다. 돌아가는 애니매이션 구현*/
}
.popup__btn-close:hover {
transform:rotate(185deg);
/*hover시 185도 돌아간다.*/
}
.popup__btn-close::before,
.popup__btn-close::after {
content:"";
background-color:black;
position:absolute;
top:40%;
left:0;
width:100%;
height:20%;
transform:rotate(45deg);
/*before, after태그를 막대기처럼 만들어 하나는 45도 하나는 -45도 기울여
X표처럼 만든다.*/
transition:box-shadow 0.3s;
/*box-shadow에 재생시간을 부여한다.*/
}
.popup__btn-close::after {
transform:rotate(-45deg);
}
.popup__btn-close:hover::before,
.popup__btn-close:hover::after {
box-shadow:0 0 3px black;
/*hover시 그림자가 생기도록 한다.*/
}
.popup__body {
padding:0 10px;
/*팝업 내용에 양엽 padding값 부여*/
}
JS
console.clear();
//popup-1을 열고 닫는 함수
function Popup1__init() {
$('.btn-popup-1').click/*.btn-popup-1을 클릭하면*/(function() {
$('.popup-1').addClass('active');/*popup-1를 가진 태그에 active클래스를 추가한다.*/
});
$('.popup-1 .popup__btn-close')/*popup-1클래스를 가진 태그의 후손인 .popup__btn-close를 클릭하면*/.click(function() {
$('.popup-1').removeClass('active');/*popup-1를 가진 태그에게서 active클래스를 제거한다.*/
});
}
Popup1__init();
//popup-2을 열고 닫는 함수
function Popup2__init() {
$('.btn-popup-2').click/*.btn-popup-2을 클릭하면*/(function() {
$('.popup-2').addClass('active');/*popup-2를 가진 태그에 active클래스를 추가한다.*/
});
$('.popup-2 .popup__btn-close')/*popup-2클래스를 가진 태그의 후손인 .popup__btn-close를 클릭하면*/.click(function() {
$('.popup-2').removeClass('active');/*popup-2를 가진 태그에게서 active클래스를 제거한다.*/
});
}
Popup2__init();
CSS코드는 동일하고 JS코드를 보면 두 함수는 서로 구별하기 위해 부여한 .popup-뒤의 숫자를 제외하면 코드가 동일하다. 이것을 이용해서 숫자 부분을 매개변수로 사용해 두 함수를 합쳐보자.
function Popup__init(no){
$('.btn-popup-' + no).click(function (){
$('.popup-' + no).addClass('active');
});
$('.popup-' + no + ' .popup__btn-close').click(function(){
$('.popup-' + no).removeClass('active');
});
}
Popup__init(1);
Popup__init(2);
이번에는 팝업창을 제외한 부분을 클릭하면 팝업이 꺼지는 것을 구현해보자. stopPropagation을 이용해야 하는데 .popup을 클릭하면 창이 꺼지도록하되 창 안을 누르면 꺼지면 안되기에 팝업창 부분인 .popup__content는 이벤트를 전파 방지로 해두면 된다.
function Popup__init(no){
$('.btn-popup-' + no).click(function (){
$('.popup-' + no).addClass('active');
});
$('.popup-' + no + ',.popup-' + no + ' .popup__btn-close').click(function(){
$('.popup-' + no).removeClass('active');
});
$('.popup-' + no + ' .popup__content').click(function(e){
e.stopPropagation();
});
/*
또는
$('.popup-' + no + ' .popup__content').click(function(){
return false;
});
*/
}
Popup__init(1);
Popup__init(2);
위 예시처럼 사용자가 웹의 크기를 줄여서 팝업의 내용을 다 담을 수 없을 때, 자동으로 내용을 담은 곳 팝업의 body부분에 스크롤 바가 생기는 것을 구현해보자.
추가해준 코드(css)
.popup__body {
max-height:calc(100vh - 54px);
/*
여기서 팝업 바디의 최대 높이는 전체 웹의 높이에서
팝업 헤더의 높이를 제외해야하므로 전체 웹 높이인 100vh에
.popup__btn-close { height:30px; }
.popup__head { padding:10px; }
.popup__content { border:2px solid black; }
30 + 10 * 2(위 아래 10px씩) + 2 * 2(위 아래 2px씩) = 54px을
뺀 값으로 한다.
*/
overflow-y:auto;
/*body의 높이가 100vh - 54px를 넘는 순간부터 자동으로 y축 스크롤이
생기도록*/
padding:0 10px;
/*양 옆 여백 만들기*/
}
추가해준 코드
css
.overflow-hidden{
overflow-y:hidden;
}
JS 함수 수정
console.clear();
function Popup__init(no) {
$('.btn-popup-' + no).click(function() {
$('.popup-' + no).addClass('active');
$('html').addClass('overflow-hidden');
/*.btn-popup-(no)(팝업(no) 버튼)을 클릭하면 html태그에
스크롤 바를 숨기는 클래스를 추가한다.*/
});
$('.popup-' + no + ' .popup__btn-close, .popup-' + no).click(function() {
$('.popup-' + no).removeClass('active');
$('html').removeClass('overflow-hidden');
/*.popup-(no)(팝업창 안 X버튼)을 클릭하면 html태그에게서
스크롤 바를 숨기는 클래스를 제거한다.*/
});
$('.popup-' + no + ' .popup__content').click(function() {
return false;
});
}
Popup__init(1);
Popup__init(2);
웹을 열면 팝업이 이미 열려있는 상태로 만들어보자. 원래의 JS함수에서 함수를 나누어서 여는 함수만 다시 작동해주면 된다.
원래 함수
console.clear();
function Popup__init(no) {
$('.btn-popup-' + no).click(function() {
/*---------------Popup__show(no);-------------*/
$('.popup-' + no).addClass('active');
$('html').addClass('popup-' + no + '-actived');
/*--------------------------------------------*/
});
$('.popup-' + no + ' .popup__btn-close, .popup-' + no).click(function() {
/*---------------Popup__hide(no);-------------*/
$('.popup-' + no).removeClass('active');
$('html').removeClass('popup-' + no + '-actived');
/*--------------------------------------------*/
});
$('.popup-' + no + ' .popup__content').click(function() {
return false;
});
}
Popup__init(1);
Popup__init(2);
수정한 함수
console.clear();
function Popup__init(no) {
$('.btn-popup-' + no).click(function() {
Popup__show(no);
});
$('.popup-' + no + ' .popup__btn-close, .popup-' + no).click(function() {
Popup__hide(no);
});
$('.popup-' + no + ' .popup__content').click(function() {
return false;
});
}
function Popup__show(no) {
$('.popup-' + no).addClass('active');
$('html').addClass('popup-' + no + '-actived');
}
function Popup__hide(no) {
$('.popup-' + no).removeClass('active');
$('html').removeClass('popup-' + no + '-actived');
}
Popup__init(1);
Popup__init(2);
Popup__show(1);
Popup__show(2);