본문 바로가기

[부트캠프] IT 코딩 부트캠프 후기/[웅진씽크빅X유데미] 스나이퍼 팩토리 🤹

[유데미x스나이퍼팩토리] Vanilla JS를 이용한 서비스 만들기 (2)

이번주에는 Java Script를 이용하여 다양한 서비스를 만들어 보고 있다. 

 


1. vanilla js로 할 일 목록 만들기

먼저 html, css, js로 각각 파일을 만든 다음에 진행하였다. 

// HTML 요소 가져오기
const completeAllBtn = document.querySelector(".complete-all-btn");
const todoInput = document.querySelector(".todo-input");
const todoList = document.querySelector(".todo-list");
const leftItems = document.querySelector(".left-items");
const showAllBtn = document.querySelector(".show-all-btn");
const showActiveBtn = document.querySelector(".show-active-btn");
const showCompletedBtn = document.querySelector(".show-completed-btn");
const clearCompletedBtn = document.querySelector(".clear-completed-btn");

Html 요소를 건드려서 수정할 것이다. 

// 할 일 리스트 배열
let todos = [];

// 할 일 객체 생성 함수
function createTodoItem(todo) {
  const listItem = document.createElement("li");
  listItem.className = "todo-item";

  const checkbox = document.createElement("div");
  checkbox.className = "checkbox";
  checkbox.innerText = "✔";

  const todoText = document.createElement("div");
  todoText.className = "todo";
  todoText.innerText = todo.text;

  const deleteBtn = document.createElement("button");
  deleteBtn.className = "delBtn";
  deleteBtn.innerText = "x";

  listItem.appendChild(checkbox);
  listItem.appendChild(todoText);
  listItem.appendChild(deleteBtn);

  // 할 일 완료 상태에 따라 스타일 변경
  if (todo.isCompleted) {
    listItem.classList.add("checked");
    checkbox.classList.add("checked");
    todoText.classList.add("checked");
  }

이벤트를 처리한다. 

  // 체크박스 클릭 이벤트 처리
  checkbox.addEventListener("click", () => {
    todo.isCompleted = !todo.isCompleted;
    listItem.classList.toggle("checked");
    checkbox.classList.toggle("checked");
    todoText.classList.toggle("checked");
    updateLeftItemsCount();
  });

  // 할 일 삭제 버튼 클릭 이벤트 처리
  deleteBtn.addEventListener("click", () => {
    const index = todos.indexOf(todo);
    if (index > -1) {
      todos.splice(index, 1);
      listItem.remove();
      updateLeftItemsCount();
    }
  });

  // 할 일 텍스트 더블 클릭 이벤트 처리
  todoText.addEventListener("dblclick", () => {
    const editInput = document.createElement("input");
    editInput.className = "edit-input";
    editInput.type = "text";
    editInput.value = todo.text;
    editInput.addEventListener("blur", () => {
      todo.text = editInput.value;
      todoText.innerText = todo.text;
      listItem.removeChild(editInput);
    });
    listItem.appendChild(editInput);
    editInput.focus();
  });

  return listItem;
}

// 할 일 추가 함수
function addTodo() {
  const todoText = todoInput.value.trim();
  if (todoText !== "") {
    const todo = {
      text: todoText,
      isCompleted: false,
    };
    todos.push(todo);
    const listItem = createTodoItem(todo);
    todoList.appendChild(listItem);
    todoInput.value = "";
    updateLeftItemsCount();
  }
}

// 전체 선택 버튼 클릭 이벤트 처리
completeAllBtn.addEventListener("click", () => {
  const isAllCompleted = todos.every((todo) => todo.isCompleted);
  todos.forEach((todo) => {
    todo.isCompleted = !isAllCompleted;
  });
  const checkboxes = document.querySelectorAll(".checkbox");
  checkboxes.forEach((checkbox) => {
    checkbox.classList.toggle("checked", !isAllCompleted);
  });
  const todoTexts = document.querySelectorAll(".todo");
  todoTexts.forEach((todoText) => {
    todoText.classList.toggle("checked", !isAllCompleted);
  });
  updateLeftItemsCount();
});

// 할 일 입력 이벤트 처리
todoInput.addEventListener("keydown", (event) => {
  if (event.key === "Enter") {
    addTodo();
  }
});

// 완료되지 않은 할 일 개수 업데이트 함수
function updateLeftItemsCount() {
  const count = todos.filter((todo) => !todo.isCompleted).length;
  leftItems.innerText = `${count} items left`;
}

// All 버튼 클릭 이벤트 처리
showAllBtn.addEventListener("click", () => {
  showAllBtn.classList.add("selected");
  showActiveBtn.classList.remove("selected");
  showCompletedBtn.classList.remove("selected");
  const todoItems = document.querySelectorAll(".todo-item");
  todoItems.forEach((item) => {
    item.style.display = "flex";
  });
});

// Active 버튼 클릭 이벤트 처리
showActiveBtn.addEventListener("click", () => {
  showAllBtn.classList.remove("selected");
  showActiveBtn.classList.add("selected");
  showCompletedBtn.classList.remove("selected");
  const todoItems = document.querySelectorAll(".todo-item");
  todoItems.forEach((item) => {
    const checkbox = item.querySelector(".checkbox");
    const isCompleted = checkbox.classList.contains("checked");
    if (isCompleted) {
      item.style.display = "none";
    } else {
      item.style.display = "flex";
    }
  });
});

// Completed 버튼 클릭 이벤트 처리
showCompletedBtn.addEventListener("click", () => {
  showAllBtn.classList.remove("selected");
  showActiveBtn.classList.remove("selected");
  showCompletedBtn.classList.add("selected");
  const todoItems = document.querySelectorAll(".todo-item");
  todoItems.forEach((item) => {
    const checkbox = item.querySelector(".checkbox");
    const isCompleted = checkbox.classList.contains("checked");
    if (isCompleted) {
      item.style.display = "flex";
    } else {
      item.style.display = "none";
    }
  });
});

// Clear Completed 버튼 클릭 이벤트 처리
clearCompletedBtn.addEventListener("click", () => {
  const completedItems = document.querySelectorAll(".todo-item.checked");
  completedItems.forEach((item) => {
    const checkbox = item.querySelector(".checkbox");
    const todoText = item.querySelector(".todo");
    const index = todos.findIndex((todo) => todo.text === todoText.innerText);
    if (index > -1) {
      todos.splice(index, 1);
      item.remove();
    }
  });
  updateLeftItemsCount();
});

할일을 초기화한다. 

// 초기화
function initialize() {
  // 기존 할 일들 초기화
  todoList.innerHTML = "";
  // 할 일 추가 이벤트 리스너 등록
  todoInput.addEventListener("keydown", (event) => {
    if (event.key === "Enter") {
      addTodo();
    }
  });
  // 버튼 선택 상태 초기화
  showAllBtn.classList.add("selected");
  showActiveBtn.classList.remove("selected");
  showCompletedBtn.classList.remove("selected");
}

// 초기화 함수 호출
initialize();


2. vanilla js로 내 위치의 날씨 만들기

강의와 비슷한 뉘앙스라 참고하기 좋을듯! 

 

Nomad Coders 강의 - VanillaJS로 크롬 momentum 만들기 2

안녕하세요.!! Lotts 입니다. 😉 저번 시간에 이어서 VanillaJS로 크롬 Momentum 만들기 ✌ 두 번째 시간입니다. 😃😃 이전 포스팅은 아래 링크를 눌러주세요 😉 2020/03/10 - [프로그래밍/JavaScript] - Nomad

msyu1207.tistory.com

 

JS | 위치 정보를 통해 현재 날씨 출력하기 ( geolocation / Weather API )

1. 위치정보 요청 geolocation.getCurrentPosition()메서드를 이용하여 사용자의 위치정보(장치의 위치)를 요청. getCurrentPosition()메서드는 최소 두 개의 매개변수를 입력받음. success와 error 콜백 함수가 기

gaemi606.tistory.com

완성!

const weather = document.querySelector(".js-weather");
const locationSpan = document.querySelector(".js-location");

const API_KEY = "api key 발급 후 복사하세요."
const COORDS = "coords";

function getWeather(lat, lng) {
  fetch(
    `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lng}&appid=${API_KEY}&units=metric`
  )
    .then(function (response) {
      return response.json();
    })
    .then(function (json) {
      const temperature = json.main.temp;
      const place = json.name;
      weather.innerText = `${temperature}°C @ ${place}`;
    });
}

function saveCoords(coordsObj) {
  localStorage.setItem(COORDS, JSON.stringify(coordsObj));
}

function handleGeoSuccess(position) {
  const latitude = position.coords.latitude;
  const longitude = position.coords.longitude;
  const coordsObj = {
    latitude,
    longitude,
  };
  saveCoords(coordsObj);
  getWeather(latitude, longitude);
}

function handleGeoError() {
  console.log("Can't access geo location");
}

function askForCoords() {
  navigator.geolocation.getCurrentPosition(handleGeoSuccess, handleGeoError);
}

function loadCoords() {
  const loadedCoords = localStorage.getItem(COORDS);
  if (loadedCoords === null) {
    askForCoords();
  } else {
    const parsedCoords = JSON.parse(loadedCoords);
    getWeather(parsedCoords.latitude, parsedCoords.longitude);
  }
}

function displayLocation(position) {
  const latitude = position.coords.latitude;
  const longitude = position.coords.longitude;
  locationSpan.innerText = `Latitude: ${latitude}, Longitude: ${longitude}`;
}

function init() {
  loadCoords();
  navigator.geolocation.getCurrentPosition(displayLocation);
}

init();

 


✍️TIL 후기

이번 마지막 2가지 과제는 오히려 앞의 3가지 과제보다 더 집중하기 좋았고, 퀄리티도 더 나아졌다고 느꼈다.

좋은 참고자료를 찾아내고, 어떻게 보완할 지 생각하는 것도 발전의 방법 중 하나라고 느낀다. 

but, 다음에는 더욱 js 자체에 집중해서 공부해야겠다. 

 

 

 

 

 

———————————————————————————————————————————————————————

본 후기는 유데미-스나이퍼팩토리 10주 완성 프로젝트캠프 학습 일지 후기로 작성 되었습니다.