이전 글
2023.06.22 - [자바스크립트] - 시베리안 허숙희의 자바스크립트 비기닝 27
의 list.htm에는 글의 제목을 클릭하면 상세내용을 모달창으로 보여주기 위해
함수 fmodal이 일부러 껍데기만 들어있당!.(모든 게 알고보면 다 안배당~~)
실제 모달창은 CSS 몇개만 알면 아주 쉽고도 쉽게 만들 수 있는 데도 불구하고,
원리 이해 없이 bootstrap의 모달 창과 씨름 하는 모습이 아쉽기만 하당. 이번 기회에
자기만의 모달창을 잘 만들어 두고, 계속 기능 확장해서 사용할 수 있길 기대본당.
먼저 모달창이 뭔지?, 왜 이걸 많이 쓰게 되었는지 생각해 보장!
예전엔 window.open을 이용하여 새창을 여는 거슬 많이 사용하였지만, 못된 사이트들이
새창 열기 지옥(도박,성인사이트등 불법사이트들이 줄줄이 계단식으로 새창에 열림 -
당시 웹개발자는 공부 초기에 이것을 구현하고,재밌어 했었당, 추억이 되었당)을
광고로 악용함으로써, 브라우져에는 새창을 열 때 사용자의 허락을 얻어야 하는 거스로
당연 바뀌었당. 그리하여 새창 열기를 이용하면 사용자가 거부해 놓았을 경우, 멧돼지를
전달할 수 없어, 그 뒤로는 대안으로 모달이 많이 사용될 수 밖에 없게 되었당.
요즘 모달은 정형화 되어서 DIV 태그를 이용해서 만드는 데, 전체화면에 꽉차는 DIV
영역을 하나의 레이어로 맹글어서 현재 보는 화면을 막아버리는 거시다.(3D 기술이당)
모달을 만들려면 CSS의 필수 기본인 position, display, z-index와 background-color 정도는
어떤 기능을 하는 지 알고 있어야 한당.( 모른다면 지금 당장 구글 껌쌕하장)
모달기본이해.html (카.복 해서 만들장)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
#modalWin{
position: fixed;
width:100vw;
height:100vh;
left:0px;
top:0px;
z-index: 1000;
/* background-color: blueviolet; */
background-color: rgba(138, 43, 226, 0.5);
display: none;
}
</style>
</head>
<body>
<div id="modalWin"></div>
<button onclick="fmodal()">모달창열기</button>
<script>
const myModalWin = document.querySelector("#modalWin");
const fmodal = function(){
myModalWin.style.display = "block";
}
</script>
</body>
</html>
posiion:fixed와 width,height,left,top을 이용하여 전체화면 크기로 화면 왼쪽 모서리에 고정했다.
z-index(숫자가 클수록 레이어가 앞으로 나온다)를 이용하여 대략 앞쪽에 나오게 했당.
display:none(아주 많이 사용)을 이용하여, 처음에는 자리차지 없이 안 보이게 했당.
버튼을 누르면 보인당.(modalWin div가 모든 걸 덮는당! 오켕?)
background-color부분을 기존 건 주석 처리하고, 주석 된 건 풀어보장(투명도 느낌온당!)
모달기본완성.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
#modalWin{
position: fixed;
width:100vw;
height:100vh;
left:0px;
top:0px;
z-index: 1000;
/* background-color: blueviolet; */
background-color: rgba(138, 43, 226, 0.5);
display: none;
}
#modalCont {
width:60%;
height:70%;
margin:10% auto;
border:3px solid black; /* 낸중에 필요없음 주석 */
background-color: brown;
}
#menu {
width:100%;
height:10%;
text-align: right;
}
#close {
font-size: 2em;
}
h1 {
text-align: center;
}
</style>
</head>
<body>
<div id="modalWin">
<div id="modalCont">
<div id="menu">
<button id="close" onclick="fmodalClose()">X</button>
</div>
<h1>이거슨 모달 내용이디용</h1>
</div>
</div>
<button onclick="fmodalOpen()">모달창열기</button>
<script>
const myModalWin = document.querySelector("#modalWin");
//모달 열기
const fmodalOpen = function(){
myModalWin.style.display = "block";
}
//모달 닫기
const fmodalClose = function(){
myModalWin.style.display = "none";
}
</script>
</body>
</html>
모달을 공부했으니, 이것을 list.html에 적용시켜 보장!
list.html에서 제목을 클릭하면, 이전 작성했던 내용이 모달에 보이기만 하믄 되므로,
write.html을 재활용하면 좋을 것이다. 대략 합치면 아래처럼 된당!
맘에 안 든다면 마음껏 고쳐 쓰도록 하장. (나의 디자인 감각은 셀프 디스 수준!)
list.html (모달 적용버젼)
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>E7E JS 께시판</title>
<link rel="shortcut icon"
href="https://img.icons8.com/?size=512&id=42814&format=png"
type="image/x-icon">
<style>
#wrapper {
width:520px;
margin: 20px auto;
color: rgb(83, 0, 161);
}
#header {
border-bottom: 2px solid orange;
text-align: center;
}
#content {
height:70vh;
overflow: auto;
}
#footer {
height:10vh;
line-height: 200%;
text-align: center;
}
#list,#list th,#list td {
border:1px solid black;
text-align: center;
}
th {
background-color: orange;
}
table {
width: 100%;
}
#modalWin{
position: fixed;
width:100vw;
height:100vh;
left:0px;
top:0px;
z-index: 1000;
/* background-color: blueviolet; */
background-color: rgba(138, 43, 226, 0.9);
display: none;
}
#modalCont {
width:400px;
height:70%;
margin:10% auto;
border:3px solid black; /* 낸중에 필요없음 주석 */
background-color: gray;
color:yellow;
text-align: center;
}
#menu {
width:100%;
height:10%;
text-align: right;
}
#close {
font-size: 2em;
}
</style>
</head>
<body>
<!-- 모달 모달 -->
<div id="modalWin">
<div id="modalCont">
<div id="menu">
<button id="close" onclick="fmodalClose()">X</button>
</div>
<div id="detail">
<form action="" method="get">
<table>
<tr><td>제목</td><td><input type="text" name="n_title" value="" required></td></tr>
<tr><td>글쓰니</td><td><input type="text" name="n_writer" value="" disabled></td></tr>
<tr><td colspan="2">내용</td></tr>
<tr><td colspan="2">
<textarea name="n_cont" cols="40" rows="10" required></textarea>
</td>
</tr>
<tr><td colspan="2">관련언어(최소1개 MAX 3개까지 선택)</td></tr>
<tr><td colspan="2">
HTML<input type="checkbox" name="n_cate" value="HTML" onclick="ckCnt(this)">
CSS<input type="checkbox" name="n_cate" value="CSS" onclick="ckCnt(this)">
JS<input type="checkbox" name="n_cate" value="JS" onclick="ckCnt(this)">
JAVA<input type="checkbox" name="n_cate" value="JAVA" onclick="ckCnt(this)">
ORACLE<input type="checkbox" name="n_cate" value="ORACLE" onclick="ckCnt(this)">
</td>
</tr>
<tr><td colspan="2"><br>
<button onclick="fPreSub('modify')">수정</button>
<button onclick="fPreSub('delete')">삭제</button>
</td>
</tr>
</table>
</form>
<div>
<img src="https://cdn.pixabay.com/photo/2019/11/28/21/31/lynx-4660096_1280.jpg"
style="width:100%;height:150px">
</div>
</div>
</div>
</div>
<!-- 화면 레이아웃-->
<div id="wrapper">
<div id="header">
<h1>어리둥절 JS 께시판</h1>
</div>
<div id="content"></div>
<div id="footer">
<h1>©E7E Compony Since 1969</h1>
</div>
</div>
<script>
//전역 변수
const myModalWin = document.querySelector("#modalWin");
const myHeader = document.querySelector("#header");
const myContent = document.querySelector("#content");
const myFooter = document.querySelector("#footer");
const myTitle = document.querySelector("[name=n_title]");
const myWriter = document.querySelector("[name=n_writer]");
const myCont = document.querySelector("[name=n_cont]");
const myCate = document.querySelectorAll("[name=n_cate]");
const tblName ="E7eBoard";
//괘니 백틱으로 써보는 템플릿
const writeLink = `
<div id="links" style="text-align:right">
<a href="write.html"><button>새글 쓰깅</button></a>
</div>
`;
let loDatas;
// Global variables
const maxCnt = 3;
let totalCnt = 0;
const myForm = document.forms[0];
let modOrDel ="";
function fPreSub(pSet){
modOrDel = pSet;
}
// Global functions
const ckCnt = function(pThis){
if(pThis.checked){
totalCnt++;
}else {
totalCnt--;
}
if(totalCnt > maxCnt){
alert("3개 까지망");
pThis.checked = !1;
totalCnt--;
}
}
myForm.onsubmit = function(){
alert(`${modOrDel}을 누르셨군용`);
event.preventDefault();
ckboxs = document.querySelectorAll("[name=n_cate]:checked");
if(ckboxs.length < 2){
alert("최소 2개는 선택하셔야 해용");
}else {
myForm.action=`${modOrDel}_action.html`;
myForm.submit();
}
}
//글 리스트 출력함수
function gulList(){
loDatas = JSON.parse(localStorage.getItem(tblName));
let tblStr = `<table id="list"><tbody>`;
tblStr += `<tr><th>글번</th><th>제목</th><th>지으니</th><th>관련</th><th>날짜</th></tr>`;
for(let i=0; i<loDatas.length; i++){
let gul = loDatas[i];
tblStr += `<tr>`;
tblStr += `<td>${gul.num}</td>`;
tblStr += `<td><a href="#" onclick="fmodalOpen('${gul.num}')">${gul.title}</a></td>`;
tblStr += `<td>${gul.writer}</td>`;
tblStr += `<td>${gul.cate}</td>`;
tblStr += `<td>${gul.date}</td>`;
tblStr += `<tr>`;
}
tblStr += `</tbody></table>`;
tblStr += writeLink;
myContent.innerHTML = tblStr;
}
//모든 태그해석이 끝나면(DOMContentLoaded 이벤트) 자동실행
window.addEventListener("DOMContentLoaded",function(){
gulList();
});
//모달 열기
const fmodalOpen = function(pNum){
event.preventDefault(); // a 태그 링크 이동 막깅
for(let i=0; i<loDatas.length; i++){
if(loDatas[i].num == pNum){
myTitle.value = loDatas[i].title;
myWriter.value = loDatas[i].writer;
myCont.value = loDatas[i].cont;
let cates = loDatas[i].cate;
totalCnt = cates.length;
for(let j=0; j < cates.length; j++){
document.querySelector(`[type=checkbox][value=${cates[j]}]`).checked = true;
}
break;
}
}
myModalWin.style.display = "block";
}
//모달 닫기
const fmodalClose = function(){
myModalWin.style.display = "none";
}
</script>
</body>
</html>
CSS 기럭지가 기러지고, write.html에 있던 스크립트도 재활용하였당.
(따로 빼면 좋은데, 보통 개발시에는 흩어져 있는 것보다 찾기 쉬운 게 좋당)
눈 뜨고 볼만한 부분은 관련언어 체크박스를 읽어온 값에 맞춰 다시 체크하는 정도!(화이팅!)
다음 글을 위해 수정/삭제 버튼 이벤트에 action을 넣어 놓았당
살다 보면 눈 과 눈 의 차이를 알아야 할 때가 있다.
눈 속에 담긴 눈에 비친 눈을 찾는 건 그런 건 일도 아니었다.
당신은 사랑 과 사랑의 차이를 아는가?
술 과 술 , 삶 과 삶의 차이, 사람 과 사람의 차이는?
아무것도 모른다면 껍데기가 아직 두껍다.
더욱 열씨미 자신을 불태우는 달리는 삶을 살아라!
껍데기가 다 타고 남은 재속에 답이 기다린당
구지 빨리 가려하진 마라, 답은 거기에 머무르니..
시베리안 허숙희의 자바스크립트 비기닝 30 (스크립트 게시판 페이징...) (0) | 2023.06.28 |
---|---|
시베리안 허숙희의 자바스크립트 비기닝 29 (스크립트 게시판 계속...) (0) | 2023.06.27 |
시베리안 허숙희의 자바스크립트 비기닝 27 ( 스크립트 게시판!) (0) | 2023.06.22 |
시베리안 허숙희의 자바스크립트 비기닝 26 (리팩토링...) (0) | 2023.06.21 |
시베리안 허숙희의 자바스크립트 비기닝 25 (LocalStorage...) (0) | 2023.06.21 |