작성 규칙
- 작성일자와 프로젝트, 작성 상태 기술
✅ 작성한 날짜를 기록함으로써 리마인드
✅ 작성한 프로젝트를 기록함으로써 프로젝트를 찾아볼 수 있음
✅ 작성 상태를 기술함으로써 수정된 이력 버전과 완성여부를 확인- 기능이름
✅ 레퍼런스 링크- 기능 설명
✅ 사용된 기술에 대해 스스로 설명- 기술 상세 기록
✅ 프로젝트에 사용한 코드를 한 줄씩 리뷰하는 것으로 코드 전체 이해 증명
✅ 코드를 설계한 내용과 왜 이렇게 작성했는지
모달 HTML
HTML 내부에 display 값이 none 으로 설정된 모달 컨테이너를 넣어두어야 함
모달 내부에 들어갈 구역을 나눈 태그를 넣어두어야 함
모달 CSS
display: none;
position: absolute;
z-index: 50;
.modal.show { display: block; }
모달 내부 설정
- 백그라운드 이미지 넣기
background-image: url("...")
보더라인에 이미지 삽입
border-style: solid;
border-width: 40px 40px 40px 40px;
-moz-border-image: url("../../static/image/source/border_image.png") 42 44 44 44 repeat repeat;
-webkit-border-image: url("../../static/image/source/border_image.png") 42 44 44 44 repeat repeat;
-o-border-image: url("../../static/image/source/border_image.png") 42 44 44 44 repeat repeat;
border-image: url("../../static/image/source/border_image.png") 42 44 44 44 repeat repeat;
모달을 페이지 가운데 올 수 있도록 비치
position: absolute;
width: 600px;
height: 800px;
padding: 40px;
border-radius: 10px;
box-shadow: 0 2px 3px 0 rgba(34, 36, 38, 0.15);
transform: translateX(-50%) translateY(-50%);
모달 크기 조정
.modal-header {
display: flex;
width: 100%;
height: 40%;
justify-content: space-between;
}
모달 내부 닫기 버튼 CSS
.x-button {
font-size: 60px;
margin-left: 60px;
cursor: pointer;
}
모달 JS
const team_summary = [
{
'name': '황영상',
'nick_name': '공상쟁이',
'mbti': 'INFP',
'strong_point': '의견을 경청하고 조율하기 위해 노력함',
'teaming_method': '프로젝트를 완수하는 것을 최우선 목표로 삼음',
'tmi_to_line': '나는 하루종일도 공상할 수 있다고!',
'img_url': '../../static/image/team_mate/ys.jpeg'
},
...
]
const body = document.querySelector('body');
const modal = document.querySelector('.modal');
const x_button = document.querySelector('.x-button');
let btns = document.querySelectorAll(".open-modal");
const status_name = document.getElementById('status-name');
const status_nickname = document.getElementById('status-nickname');
const status_mbti = document.getElementById('status-mbti');
const strong_point = document.getElementById('strong-point')
const teaming_method = document.getElementById('teaming-method');
const tmi_to_line = document.getElementById('tmi-to-line');
const status_img_url = document.getElementById('status-image');
[].forEach.call(btns, function (col) {
col.addEventListener('click', (e) => {
open_modal(e)
})
});
function open_modal(e) {
// 이벤트를 가져와 num 변수에 저장해 어떤 버튼이 눌러졌는지 확인한다.
let num = e.target.classList[1]
// 각 javascript object를 제어해서 값을 변경한다.
status_name.innerHTML = team_summary[num].name
status_nickname.innerHTML = team_summary[num].nick_name
status_mbti.innerHTML = team_summary[num].mbti
strong_point.innerHTML = team_summary[num].strong_point
teaming_method.innerHTML = team_summary[num].teaming_method
tmi_to_line.innerHTML = team_summary[num].tmi_to_line
status_img_url.src = team_summary[num].img_url
// 모달을 화면을 보여준다.
modal.style.top = ((window.innerHeight - modal.scrollHeight) / 2 + window.scrollY) + "px"
modal.style.left = ((window.innerWidth - modal.scrollWidth) / 2 + window.scrollX) + "px"
modal.classList.toggle('show');
if (modal.classList.contains('show')) {
body.style.overflow = 'hidden';
}
}
modal.classList.toggle('show');
body.style.overflow = 'hidden';
body.style.overflow = 'auto';
// 모달이 켜졌을 때/꺼졌을 때
modal.addEventListener('click', (event) => {
if (event.target === modal) {
// 모달이 켜졌다면 끄고, 꺼졌다면 키기
modal.classList.toggle('show');
// 모달이 꺼진다면 스크롤바 다시 생기기
if (!modal.classList.contains('show')) {
body.style.overflow = 'auto';
}
}
});
// ESC 키를 눌렀을 때
document.addEventListener('keyup', function (e) {
if ((e.key === "Escape") && (modal.classList.contains('show'))) {
modal.classList.toggle('show')
body.style.overflow = 'auto';
}
})
// 모달 폼의 X 버튼을 클릭했을 때
x_button.addEventListener('click', function () {
modal.classList.toggle('show');
if (!modal.classList.contains('show')) {
body.style.overflow = 'auto';
}
})
<div class="modal">
<div class="modal-container">
<div class="modal-header">
<!-- status 창 이미지 태그 -->
<img src="" class="team-image" id="status-image">
<div class="name-strong-point">
<!-- id 값을 지정해서 text값 변경 기능 추가 가능 >> 코드를 일일이 치기 보다는 만들어 놓은 부분 재사용 가능 -->
<p class="name" id="status-name"></p>
<!-- 닉네임 아이디 지정 -->
<p class="nickname" id="status-nickname"></p>
</div>
<div class="x-button">x</div>
</div>
<div class="modal-body">
<div class="modal-body-row1">
<!-- level은 0으로 지정 우리는 다 초보니까 ^^-->
<div class="blue-status-category">
lv : <span class="status-content">0</span>
</div>
<!-- mbti id 지정-->
<div class="blue-status-category" id="status-mbti">
mbti : <span class="status-content"></span>
</div>
</div>
<div class="modal-body-row2">
<div class="blue-status-category">
<!-- 장점 아이디 생성 -->
장점 : <span class="status-content" id="strong-point"></span>
</div>
<div class="blue-status-category">
<!-- 협업 스타일 아이디 생성 -->
협업 스타일 : <span class="status-content" id="teaming-method"></span>
</div>
</div>
<div class="modal-body-row2">
<!-- tmi를 옮긴 대사 아이디 생성 -->
<div class="status-content" id="tmi-to-line">
</div>
</div>
</div>
</div>
</div>
/* 모달 크기, display none 이다가 버튼이 눌려지면 밑에
modal.show가 불리면서 모달창이 켜짐*/
.modal {
/* 모달 화면 위치 고정 */
position: absolute;
top: 0;
left: 0;
z-index: 50;
/* 버튼을 눌러 모달을 실행해야 하므로 display 값을 none */
display: none;
background-color: rgba(0, 0, 0, 0.4);
}
/* 버튼을 눌렀을 때, 모달을 켜기 */
.modal.show {
display: block;
}
/* 모달 내부 설정 */
.modal-container {
/* 종이 질감을 백그라운드에 넣음*/
background-image: url("../../static/image/source/old_paper.jpeg");
background-size: cover;
color: dimgray;
/* 보더라인에 액자 이미지를 넣음 (올드게임 스테이터스) */
border-style: solid;
border-width: 40px 40px 40px 40px;
-moz-border-image: url("../../static/image/source/border_image.png") 42 44 44 44 repeat repeat;
-webkit-border-image: url("../../static/image/source/border_image.png") 42 44 44 44 repeat repeat;
-o-border-image: url("../../static/image/source/border_image.png") 42 44 44 44 repeat repeat;
border-image: url("../../static/image/source/border_image.png") 42 44 44 44 repeat repeat;
/* 모달을 페이지 가운데 올 수 있도록 비치*/
position: absolute;
width: 600px;
height: 800px;
padding: 40px;
border-radius: 10px;
box-shadow: 0 2px 3px 0 rgba(34, 36, 38, 0.15);
transform: translateX(-50%) translateY(-50%);
}
/* 모달 크기 조정 */
.modal-body {
width: 100%;
height: 50%;
}
/* 모달 헤더: 사진, 이름 부문 */
.modal-header {
display: flex;
width: 100%;
height: 40%;
justify-content: space-between;
}
/* 모달 헤더 : 제목 부분 */
.name-strong-point {
margin-left: 60px;
}
/* 모달 헤더 : 이름 부분 */
.name {
color: cornflowerblue;
margin-top: 30px;
font-weight: bold;
font-size: 50px;
}
/* 모달 헤더 : 닉네임 부분 */
.nickname {
margin: 60px 0 0 5px;
font-size: 35px;
}
/* 모달 바디 : 스테이터스 부분 */
.blue-status-category {
margin-top: 30px;
color: cornflowerblue;
font-size: 40px;
width: 100%;
}
/* 모달 바디 : 첫번째 줄 */
.modal-body-row1 {
width: 100%;
display: flex;
}
/* 모달 바디 : 두번째 줄 */
.modal-body-row2 {
width: 100%;
display: block;
}
/* 모달 바디 : 내용 부분 */
.status-content {
margin-top: 30px;
color: dimgray;
font-size: 40px;
}
/* 모달 X버튼 크기 속성 */
.x-button {
font-size: 60px;
margin-left: 60px;
cursor: pointer;
}
// 모달에 동적으로 붙일 데이터 선언
const team_summary = [
{
'name': '황영상',
'nick_name': '공상쟁이',
'mbti': 'INFP',
'strong_point': '의견을 경청하고 조율하기 위해 노력함',
'teaming_method': '프로젝트를 완수하는 것을 최우선 목표로 삼음',
'tmi_to_line': '나는 하루종일도 공상할 수 있다고!',
'img_url': '../../static/image/team_mate/ys.jpeg'
},
{
'name': '이민기',
'nick_name': '세딸아빠',
'mbti': 'ENFP',
'strong_point': '사교적인 성격으로 팀과의 친밀감 형성을 잘함',
'teaming_method': '자신에게 주어진 바에 최선을 다하기, 약속 준수',
'tmi_to_line': '세이브 로드가 없는 프린세스 메이커중... 눈에서 흐르는 건 땀이겠지?',
'img_url': '../../static/image/team_mate/mk.jpg'
},
{
'name': '김하진',
'nick_name': '그로잉 집착남',
'mbti': 'ENFP',
'strong_point': '흥미있는 일에는 굉장한 몰입도',
'teaming_method': '맡은 일은 반드시 마무리하기, 약속 준수',
'tmi_to_line': '고양이, 물고기, 풀떼기 다음은 뭘 키워볼까?',
'img_url': '../../static/image/team_mate/hj.jpg'
},
{
'name': '주정한',
'nick_name': '자유로운 영혼',
'mbti': 'ENTP',
'strong_point': '성장 지향적인 성격과 실천력',
'teaming_method': '다수가 납득할 수 있는 합의점을 찾는 것과 토론하기',
'tmi_to_line': '엄청난 귀차니즘 때문에 뭘 하려면 마음을 다섯번은 먹어야 해!',
'img_url': '../../static/image/team_mate/joo.jpeg'
},
]
//모달로직을 수행하기 위한 object들
const body = document.querySelector('body');
const modal = document.querySelector('.modal');
const x_button = document.querySelector('.x-button');
let btns = document.querySelectorAll(".open-modal");
// 데이터 변경을 위한 각각의 javascript object값을 각 변수에 저장
const status_name = document.getElementById('status-name');
const status_nickname = document.getElementById('status-nickname');
const status_mbti = document.getElementById('status-mbti');
const strong_point = document.getElementById('strong-point')
const teaming_method = document.getElementById('teaming-method');
const tmi_to_line = document.getElementById('tmi-to-line');
const status_img_url = document.getElementById('status-image');
// 모달을 제어하기 위해 전체 버튼들에 대해서 이벤트 리스너를 적용함
[].forEach.call(btns, function (col) {
col.addEventListener('click', (e) => {
open_modal(e)
})
});
// 모달을 오픈하는 메서드
function open_modal(e) {
// 이벤트를 가져와 num 변수에 저장해 어떤 버튼이 눌러졌는지 확인한다.
let num = e.target.classList[1]
// 각 javascript object를 제어해서 값을 변경한다.
status_name.innerHTML = team_summary[num].name
status_nickname.innerHTML = team_summary[num].nick_name
status_mbti.innerHTML = team_summary[num].mbti
strong_point.innerHTML = team_summary[num].strong_point
teaming_method.innerHTML = team_summary[num].teaming_method
tmi_to_line.innerHTML = team_summary[num].tmi_to_line
status_img_url.src = team_summary[num].img_url
// 모달을 화면을 보여준다.
modal.style.top = ((window.innerHeight - modal.scrollHeight) / 2 + window.scrollY) + "px"
modal.style.left = ((window.innerWidth - modal.scrollWidth) / 2 + window.scrollX) + "px"
modal.classList.toggle('show');
if (modal.classList.contains('show')) {
body.style.overflow = 'hidden';
}
}
// 모달이 켜졌을 때
modal.addEventListener('click', (event) => {
if (event.target === modal) {
modal.classList.toggle('show');
if (!modal.classList.contains('show')) {
body.style.overflow = 'auto';
}
}
});
// ESC 키를 눌렀을 때
document.addEventListener('keyup', function (e) {
if ((e.key === "Escape") && (modal.classList.contains('show'))) {
modal.classList.toggle('show')
body.style.overflow = 'auto';
}
})
// 모달 폼의 X 버튼을 클릭했을 때
x_button.addEventListener('click', function () {
modal.classList.toggle('show');
if (!modal.classList.contains('show')) {
body.style.overflow = 'auto';
}
})