티스토리 뷰
통합 달력 스크립트 (년월 이동 오늘 일정 자동 표시).html
0.01MB
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JS 일정 관리 달력</title>
<style>
:root {
--primary-color: #4a90e2;
--event-dot-color: #ff4d4d;
--today-bg: #fff9c4;
}
body { font-family: 'Pretendard', sans-serif; display: flex; justify-content: center; padding: 20px; background-color: #f5f5f5; }
.calendar-container {
width: 400px;
background: #fff;
padding: 20px;
border-radius: 12px;
box-shadow: 0 10px 25px rgba(0,0,0,0.1);
}
/* 헤더 스타일 */
.calendar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.nav-buttons { display: flex; gap: 8px; align-items: center; }
select { padding: 5px; border-radius: 4px; border: 1px solid #ddd; cursor: pointer; }
button {
background: var(--primary-color);
color: white; border: none;
padding: 5px 12px; border-radius: 4px; cursor: pointer;
}
button:hover { opacity: 0.8; }
/* 달력 그리드 */
.weekdays {
display: grid;
grid-template-columns: repeat(7, 1fr);
font-weight: bold;
text-align: center;
color: #666;
margin-bottom: 10px;
}
.calendar-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 5px;
}
.day {
aspect-ratio: 1 / 1;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
border-radius: 8px;
position: relative;
transition: 0.2s;
font-size: 14px;
}
.day:hover { background: #eef2ff; }
.day.today { background: var(--today-bg); font-weight: bold; color: #d4a017; border: 1px solid #fbc02d; }
/* 일정 점 표시 */
.has-event::after {
content: '';
position: absolute;
bottom: 6px;
width: 5px;
height: 5px;
background-color: var(--event-dot-color);
border-radius: 50%;
}
/* 하단 일정 리스트 */
.event-section {
margin-top: 25px;
padding-top: 15px;
border-top: 1px dashed #ddd;
}
.event-section h3 { font-size: 16px; margin-bottom: 10px; color: #333; }
#eventList { list-style: none; padding: 0; margin: 0; }
#eventList li {
padding: 8px 12px;
background: #f9f9f9;
margin-bottom: 5px;
border-radius: 6px;
font-size: 14px;
border-left: 3px solid var(--primary-color);
}
.no-event { color: #999; font-style: italic; border-left: none !important; background: none !important; }
</style>
</head>
<body>
<div class="calendar-container">
<div class="calendar-header">
<div class="nav-buttons">
<button id="prevMonth"><</button>
<select id="yearSelect"></select>
<select id="monthSelect"></select>
<button id="nextMonth">></button>
</div>
<button onclick="goToToday()">오늘</button>
</div>
<div class="weekdays">
<div style="color:red">일</div><div>월</div><div>화</div><div>수</div><div>목</div><div>금</div><div style="color:blue">토</div>
</div>
<div id="calendarGrid" class="calendar-grid"></div>
<div class="event-section">
<h3 id="selectedDateTitle">날짜를 선택하세요</h3>
<ul id="eventList"></ul>
</div>
</div>
<script>
// 1. 가상 일정 데이터 (테스트용)
const scheduleData = {
"2026-03-03": ["오늘은 서비스 오픈일!", "팀 회식 19:00"],
"2026-03-05": ["프로젝트 마감일"],
"2026-03-14": ["화이트데이 캔들 만들기"],
"2026-04-01": ["만우절 장난 준비"]
};
let viewDate = new Date(); // 현재 화면에 보이는 기준 날짜
const yearSelect = document.getElementById('yearSelect');
const monthSelect = document.getElementById('monthSelect');
const grid = document.getElementById('calendarGrid');
const listEl = document.getElementById('eventList');
const titleEl = document.getElementById('selectedDateTitle');
// 초기화 함수
function init() {
const currentYear = new Date().getFullYear();
// 년도 선택 범위: 현재 기준 ±5년
for (let i = currentYear - 5; i <= currentYear + 5; i++) {
const opt = document.createElement('option');
opt.value = i; opt.innerText = i + "년";
yearSelect.appendChild(opt);
}
// 월 선택
for (let i = 0; i < 12; i++) {
const opt = document.createElement('option');
opt.value = i; opt.innerText = (i + 1) + "월";
monthSelect.appendChild(opt);
}
renderCalendar();
// [핵심] 로딩 시 오늘 날짜 일정 바로 표시
const todayStr = formatDate(new Date());
showEvents(todayStr);
}
// 날짜 포맷팅 유틸리티 (YYYY-MM-DD)
function formatDate(date) {
const y = date.getFullYear();
const m = String(date.getMonth() + 1).padStart(2, '0');
const d = String(date.getDate()).padStart(2, '0');
return `${y}-${m}-${d}`;
}
// 달력 그리기
function renderCalendar() {
const year = viewDate.getFullYear();
const month = viewDate.getMonth();
yearSelect.value = year;
monthSelect.value = month;
grid.innerHTML = '';
const firstDay = new Date(year, month, 1).getDay();
const lastDate = new Date(year, month + 1, 0).getDate();
const todayStr = formatDate(new Date());
// 시작 요일 맞추기 위한 빈칸
for (let i = 0; i < firstDay; i++) grid.innerHTML += `<div></div>`;
// 날짜 생성
for (let d = 1; d <= lastDate; d++) {
const dateStr = `${year}-${String(month + 1).padStart(2, '0')}-${String(d).padStart(2, '0')}`;
const dayDiv = document.createElement('div');
dayDiv.className = 'day';
if (dateStr === todayStr) dayDiv.classList.add('today');
if (scheduleData[dateStr]) dayDiv.classList.add('has-event');
dayDiv.innerText = d;
dayDiv.onclick = () => showEvents(dateStr);
grid.appendChild(dayDiv);
}
}
// 일정 리스트 업데이트
function showEvents(dateStr) {
const isToday = dateStr === formatDate(new Date());
titleEl.innerText = isToday ? `오늘 (${dateStr})` : dateStr;
const events = scheduleData[dateStr] || [];
if (events.length > 0) {
listEl.innerHTML = events.map(e => `<li>${e}</li>`).join('');
} else {
listEl.innerHTML = `<li class="no-event">일정이 없습니다.</li>`;
}
}
// 오늘로 이동 버튼
function goToToday() {
viewDate = new Date();
renderCalendar();
showEvents(formatDate(viewDate));
}
// 이벤트 리스너
yearSelect.onchange = () => { viewDate.setFullYear(yearSelect.value); renderCalendar(); };
monthSelect.onchange = () => { viewDate.setMonth(monthSelect.value); renderCalendar(); };
document.getElementById('prevMonth').onclick = () => {
viewDate.setMonth(viewDate.getMonth() - 1);
renderCalendar();
};
document.getElementById('nextMonth').onclick = () => {
viewDate.setMonth(viewDate.getMonth() + 1);
renderCalendar();
};
init();
</script>
</body>
</html>
※ 해당 내용은 Google Gmini3.0에서 작성되었습니다.
'WEB > JavaScript' 카테고리의 다른 글
| 6주 카테고리 달력 (0) | 2026.03.04 |
|---|---|
| 카테고리 기능이 추가된 달력 스크립트 (년/월 이동 + 오늘 일정 자동 표시) (0) | 2026.03.03 |
| 실시간 검색 필터링 (0) | 2026.01.14 |
| [JavaScript]슬라이드 이미지 (0) | 2026.01.03 |
| [JavaScript] 비밀번호가 8자 이상이고 특수문자가 포함여부 체크하기 (0) | 2026.01.03 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 파비콘 #파비콘 사이트에 적용
- lg그램pro #lg그램 #노트북 #노트북추천 #lg노트북
- 정보처리기사 #정보처리기사요약 #정보처리기사요점정리
- 좋은책
- 증폭기 #아이피타임증폭기
- 좋은책 #밥프록터 #부의원리
- 자바스크립트break
- SQL명령어 #SQL
- 자바스크립트 #javascript #math
- // 사진직: 데이터가 없으면 DEFAULT_IMG 사용 const profileSrc = (d.img && d.img !== "") ? d.img : DEFAULT_IMG;('#user-photo').attr('src'
- thymeleaf
- 썬크림 #닥터지썬크림 #내돈내산 #내돈내산썬크림 #썬크림추천 #spf50썬크림 #닥터지메디유브이울트라선
- 자바스크립트countiue
- css미디어쿼리 #미디어쿼리 #mediaquery
- jdk #jre
- 무료폰트 #무료웹폰트 #한수원한돋움 #한수원한울림 #한울림체 #한돋움체
- sw기술자평균임금 #2025년 sw기술자 평균임금
- 광주분식 #광주분식맛집 #상추튀김 #상추튀김맛집 #광주상추튀김
- iptime와이파이증폭기 #와이파이증폭기설치
- 와이파이증폭기추천 #와이파이설치
- echart
- 파비콘사이즈
- ajax
- 바지락칼국수 #월곡동칼국수 #칼국수맛집
- 테스크탑무선랜카드 #무선랜카드 #아이피타이무선랜카드 #a3000mini #무선랜카드추천
- 연명의료결정제도 #사전연명의료의향서 #사전연명의료의향서등록기관 #광주사전연명의료의향서
- jQuery #jQuery이미지슬라이드 #이미지슬라이드
- 탭메뉴자바스크립트
- 자바스크립트정규표현식
- 쇼팬하우어 #좋은책
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
글 보관함

