IT/Javascript

JavaScript: 나만의 대시보드 만들기 (2) - 날씨 정보와 투두 리스트 결합 🌤️📝

초코스타 2026. 5. 5. 10:50

안녕하세요, 독자 여러분! 개발자의 삶입니다. 😊

38일차 포스팅에서는 텅 빈 화면에 실시간 시계를 띄우고, 사용자에게 이름을 물어보아 기억하는 대시보드의 기초 뼈대를 만들었습니다. 입력한 이름이 나타나며 시계가 째깍거리는 모습에 뿌듯함을 느끼셨을 텐데요.

오늘은 이 대시보드를 진정한 나만의 비서로 업그레이드하는 시간입니다. 31일차와 32일차에 배웠던 위치 기반 날씨 정보, 그리고 26일차에 완성했던 영구 저장 투두 리스트를 이 대시보드 화면에 하나로 합쳐보겠습니다.

1. 도입

지금까지 우리는 각각의 기능들을 따로따로 배웠습니다. 시계 파일, 날씨 파일, 투두 리스트 파일이 다 따로 있었죠. 하지만 웹 개발의 진짜 묘미는 이렇게 만들어진 작은 부품(컴포넌트)들을 하나의 화면에 모아서 거대한 서비스를 조립하는 데 있습니다.

오늘은 기존 HTML에 날씨와 할 일을 보여줄 자리를 만들고, 자바스크립트로 해당 기능들을 연결하는 작업에 집중해 보겠습니다.

2. 날씨 정보 띄우기 (Weather API 결합)

먼저 HTML 파일의 원하는 위치(보통 우측 상단)에 날씨 정보가 들어갈 공간을 만들어 줍니다.

HTML
 
<div id="weather">
    <span></span> <span></span> </div>

이제 자바스크립트로 내 위치를 찾고 날씨 서버(OpenWeatherMap)에 데이터를 요청하는 코드를 추가합니다.

JavaScript
 
// app.js (혹은 weather.js로 파일을 분리해도 좋습니다)

const weather = document.querySelector("#weather span:first-child");
const city = document.querySelector("#weather span:last-child");

// API_KEY에는 여러분이 OpenWeatherMap에서 발급받은 키를 넣으세요!
const API_KEY = "여기에_발급받은_API_키를_넣습니다";

function onGeoOk(position) {
    const lat = position.coords.latitude;
    const lon = position.coords.longitude;
    const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`;

    fetch(url)
        .then((response) => response.json())
        .then((data) => {
            city.innerText = data.name;
            weather.innerText = `${data.weather[0].main} / ${data.main.temp}℃`;
        });
}

function onGeoError() {
    alert("위치를 찾을 수 없어 날씨 정보를 가져올 수 없습니다.");
}

// 브라우저에게 위치 정보 권한을 요청하고 실행합니다.
navigator.geolocation.getCurrentPosition(onGeoOk, onGeoError);

3. 영구 저장 투두 리스트 붙이기 (Todo List 결합)

대시보드 하단에는 우리가 매일 확인해야 할 할 일 목록이 필요합니다. HTML에 입력 폼과 리스트가 들어갈 자리를 마련합니다.

HTML
 
<form id="todo-form">
    <input type="text" placeholder="오늘의 할 일을 적어보세요" required />
</form>
<ul id="todo-list"></ul>

자바스크립트에는 26일차에 작성했던 투두 리스트의 핵심 로직(생성, 삭제, 저장, 불러오기)을 그대로 가져와 연결합니다.

JavaScript
 
// app.js

const toDoForm = document.getElementById("todo-form");
const toDoInput = document.querySelector("#todo-form input");
const toDoList = document.getElementById("todo-list");

const TODOS_KEY = "todos";
let toDos = []; // 할 일을 담을 배열

function saveToDos() {
    localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
}

function deleteToDo(event) {
    const li = event.target.parentElement;
    li.remove();
    toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id));
    saveToDos();
}

function paintToDo(newTodo) {
    const li = document.createElement("li");
    li.id = newTodo.id;
    const span = document.createElement("span");
    span.innerText = newTodo.text;
    const button = document.createElement("button");
    button.innerText = "❌";
    button.addEventListener("click", deleteToDo);
    
    li.appendChild(span);
    li.appendChild(button);
    toDoList.appendChild(li);
}

function handleToDoSubmit(event) {
    event.preventDefault();
    const newTodo = toDoInput.value;
    toDoInput.value = "";
    const newTodoObj = {
        text: newTodo,
        id: Date.now(),
    };
    toDos.push(newTodoObj);
    paintToDo(newTodoObj);
    saveToDos();
}

toDoForm.addEventListener("submit", handleToDoSubmit);

const savedToDos = localStorage.getItem(TODOS_KEY);

if (savedToDos !== null) {
    const parsedToDos = JSON.parse(savedToDos);
    toDos = parsedToDos;
    parsedToDos.forEach(paintToDo);
}

4. 코드 종합 및 실행 원리

이렇게 코드를 합치면, 브라우저가 열릴 때 자바스크립트는 다음과 같이 바쁘게 움직입니다.

  1. 시계 실행: setInterval을 통해 1초마다 화면의 시간을 갱신합니다.
  2. 사용자 확인: LocalStorage를 뒤져서 이름이 있으면 인사말을, 없으면 로그인 폼을 띄웁니다.
  3. 날씨 요청: 브라우저 GPS를 켜서 좌표를 찾은 뒤, Fetch로 서버에 날씨를 물어보고 화면 구석에 온도를 적어줍니다.
  4. 할 일 복구: LocalStorage를 뒤져서 예전에 저장해 둔 할 일 배열이 있다면 꺼내서 화면에 차례대로 그려줍니다.

이 모든 작업이 1초도 안 되는 찰나의 순간에 독립적으로, 동시에 일어납니다. 이것이 바로 우리가 그동안 배운 자바스크립트의 힘입니다!

5. 마무리

오늘은 39일차 포스팅으로, 외부 API와 LocalStorage 데이터를 한 화면에 결합하여 완벽한 기능을 갖춘 나만의 대시보드를 완성했습니다.

단순히 변수와 반복문을 배우던 시절에서 시작해, 이제는 브라우저의 저장소와 외부 서버까지 넘나드는 훌륭한 웹 애플리케이션을 직접 손으로 만들어 내셨습니다. 정말 감격스러운 순간이 아닐 수 없습니다. 이 코드에 여러분만의 CSS 스타일을 입혀서 더욱 예쁘게 꾸며보시길 권해드립니다.

내일은 드디어 우리의 40일간의 여정을 마무리하는 대망의 40일차 포스팅입니다.

 

마지막까지 화이팅입니다! 다음 시간에 만나요! 👋