초기 달력 모습
- border-collapse 표 테두리(border)를 분리(separated)할지 합칠지(collapsed)를 결정합니다.
이거 안쓰면 HTML 기본이 분리(spearated)라서 표에 간격이 생긴다.
이런식으로 말이다. ↓
width, height 서식주기
- td에 높이와 넓이 120px씩 주었다.
요일을 td-> th로 변경
- th태그는 컬럼 제목을 표시하기 위한 thread 태그로 th 태그에는
{ text-align: center; font-weight: bold } 서식이 디폴트로 적용된다. 따라서 더 적합하다.
- 그 후에 th 스타일 속성을 더 주었다.
vertical-align 서식
:nth-child(n) 셀렉터
- td th 의 첫번째 글자 색을 빨간색으로 변경
- nth-last-child(1)의 경우 td의 자식중 마지막 요소를 지정
- 동일한 서식을 부여할 때, CSS 셀렉터에서 쉼표문자로 태그를 나열하면 보기 더 좋다! (쉼표빼면 부모 자식 의미가 되어버림)
적용하면 이런 모습 ↓ 토,일에 색 지정
block 태그와 inline 태그
가로 방향으로 한 줄을 다 차지하는 태그를 block태그라고 하고,
그렇지 않은 태그를 inline 태그라고 부릅니다.
- block 요소
<address>, <article>, <aside>, <blockgquote>, <canvas>, <dd>, <div>, <dl>, <hr>, <header>, <form>,<h2>, <h2>, <h3>, <h4>, <h5>, <h6>, <table>, <pre>, <ul>, <p>, <ol>, <video>- inline 요소
<span>, <a>, <i>, <abbr>, <img>, <strong>, <b>, <input>, <sub>, <br>, <code>, <em>, <small>, <tt>, <map>, <textarea>, <label>, <sup>, <q>, <button>, <cite>
- block
block은 한 영역을 차지 하는 박스형태 을 가지는 성질입니다. 그렇기 때문에 기본적으로 block은 width값이 100%가 됩니다. 그리고 라인이 새로 추가된다는 것을 알 수 있습니다.block은 height와 width 값을 지정 할 수 있다.
block은 margin과 padding을 지정 할 수 있다.
- inline
inline은 주로 텍스트를 주입 할 때 사용 되는 형태입니다. 그렇기 때문에 기본적으로 block처럼 width값이 100%가 아닌 컨텐츠 영역 만큼 자동으로 잡히게 되며 라인이 새로 추가 되지 않습니다. 높이 또한 폰트의 크기만큼 잡힙니다.(line-height로 설정이 가능 하긴 합니다.)width와 height를 명시 할 수 없다.
margin은 위아래엔 적용 되지 않는다.
padding은 좌우는 공간과 시각적인 부분이 모두 적용 되지만 위아래는 시각적으로는 추가되지만 공간을 차지 하지는 않는다.
- inline-block
inline-block 은 말그대로 inline의 특징과 block의 특징을 모두 가진 요소입니다. inline-block의 특징은 다음과 같습니다.줄바꿈이 이루어지지 않는다.
block처럼 width와 height를 지정 할 수 있다.
만약 width와 height를 지정하지 않을 경우, inline과 같이 컨텐츠만큼 영역이 잡힌다.
출처 : //seungwoohong.tistory.com/23
출처 : 이승진 교수님 수업
export class ImCalendar{
constructor(){
this.today = new Date();
this.date = new Date();
this.cnt = 0;
this.row = undefined;
this.cell = undefined;
this.isPrevNext = undefined;
this.HL_today = false;
}
/* 🔰 */
startDraw(obj){
const targetName = obj.target;
const target = document.getElementById(targetName);
const btn_prevNext = obj.prevNext ?? true;
this.HL_today = obj.HL_today ?? false;
this.reset_sect(target);
this.makeYM(target,btn_prevNext);
this.make_calendar(target,obj);
}
reset_sect(target){
target.classList.add('sect_cal');
target.innerHTML = '';
}//reset_sect
/* 🔰 */
makeYM(target,btn_prevNext){
const article_YM = document.createElement('ARTICLE');
article_YM.classList.add('YM');
if(btn_prevNext){
article_YM.innerHTML = `
<button class="btn_month-prev" data-month="prev">이전달</button>
<div class="title">YYYY년 MM달</div>
<button class="btn_month-next" data-month="next">다음달</button>
`;
}else{
article_YM.innerHTML = `
<div class="title">YYYY년 MM달</div>
`;
}
target.appendChild(article_YM);
article_YM.addEventListener('click', e => {this.onClick(e)});
}//reset_sect
/* 🔰 */
make_calendar(target,obj){
const tbl = document.createElement('TABLE');
tbl.classList.add('tbl_cal');
target.appendChild(tbl);
this.make_thead(tbl);
this.display_calendar(tbl,obj);
}//make_calendar
make_thead(tbl){
const content = `
<thead>
<tr>
<th>SUN</th> <th>MON</th> <th>TUE</th> <th>WED</th> <th>THU</th> <th>FRI</th> <th>SAT</th>
</tr>
</thead>
<tbody>
<tr>
</tr>
</tbody>
`;
tbl.innerHTML = content;
}//make_thead
display_calendar(tbl){
const tbody = tbl.getElementsByTagName('TBODY')[0];
const doMonth = new Date(this.today.getFullYear(), this.today.getMonth(), 1);
const lastDate = new Date(this.today.getFullYear(), this.today.getMonth() + 1, 0);
this.setYM(tbl)
this.reset_tbody(tbody, doMonth);
this.draw_dates(tbody,lastDate);
}//display_calendar
setYM(tbl){
const title = tbl.previousElementSibling.getElementsByClassName('title')[0];
title.innerHTML = `${this.today.getFullYear()}년 ${this.today.getMonth()+1}월`;
}//setYM
reset_tbody(tbody, doMonth){
tbody.innerHTML = '';
this.row = null;
this.row = tbody.insertRow();
this.cnt = 0;
for(let i=0; i<doMonth.getDay(); i++){
this.cell = this.row.insertCell();
this.cnt++;
}
}//reset_tbody
draw_dates(tbody,lastDate){
for(let i=1; i<=lastDate.getDate(); i++){
this.cell = this.row.insertCell();
this.cell.innerHTML = i;
this.cnt++;
if(this.cnt % 7 == 1){this.cell.classList.add('sunday');}
if(this.cnt % 7 == 0){
this.cell.classList.add('saturday');
this.row = tbody.insertRow();
}//if
if(this.HL_today){this.draw_today(i);}
}//for
}//draw_dates
onClick(e){
e = e || window.event;
if(e.target.tagName != "BUTTON"){return;}
this.isPrevNext = e.target.dataset.month == "prev" ? -1 : 1;
this.today = new Date(this.today.getFullYear(),this.today.getMonth() + this.isPrevNext, this.today.getDate());
const tbl = e.currentTarget.nextElementSibling;
this.display_calendar(tbl);
}//onClick
draw_today(i){
const is_today_true = this.is_today_true(i);
if(is_today_true){this.cell.classList.add('today');}
}//draw_this.today
is_today_true(i){
if (this.today.getFullYear() == this.date.getFullYear() &&
this.today.getMonth() == this.date.getMonth() &&
i == this.date.getDate()){
return true;
}//if
}//is_this.today_true
}//[CLASS] : ImCalendar