#3 JS APP 만들기

w=j·2021년 5월 19일
0

1.clock.js

  • 화면에 시간 표시하기

  • HTML

<div class="js-clock">
        <h1>00:00</h1>
</div>

html 해당 태그를 추가하고 해당 div 태그 클래스 "js-clock"를 추가한다.

  • 자바스크립트에서 해당 클래스 값을 이용하여 해당태그를 수정하기 위해서이다.
  • Javascript
const clockContainer = document.querySelector(".js-clock"),
      clockContainer     = clockContainer.querySelector("h1");
  • doucument 객체의 querySelector() 메서드를 사용하야 html의 태그를 반환한다.
  • 해당 메서드의 인자가 클래스이면 ".", id이면 "#"을 앞에 붙인다.
  • 해당 반환된 태그(clockContainer) 에서 h1 태그를 찾아 반환한다.
  • 각 각 반환된 태그를 변수 clockContainer, clockContainer에 할당한다.
function getTime() {
    
}

function init() {
    getTime();
}

init();
  • init() 함수를 선언하여 해당 자바스크립트에서는 다른 함수들을 실행 할때는 init()함수 내에서 실행 하도록 함.
  • getTime() 함수 : 시간정보를 받아와 화면에 출력하는 함수
const clockContainer = document.querySelector(".js-clock"),
      clockTitle     = clockContainer.querySelector("h1");

function getTime() {
    
}

function init() {
    getTime();
}

init();
      
  • 변수 clockContainer : html에서 클래스가 "js-clock"인 태그를 찾아 반환.
    시간을 표시하는 부분을 포함하는 태그
<div class="js-clock">
        <h1>00:00</h1>
</div>
  • 변수 clockTitle : clockContainer안에 "h1" 태그를 찾아 반환.
<h1>00:00</h1>
  • Date 객체
  • 날짜와 시간을 나타내는 객체
  • 사용 방법
  • Date() 생성자를 사용하요 객체를 생성하고 생성한 인스턴스에 프로퍼티들을 접근하여 사용한다.
const date = new Date();
date.getDay(); // 일
date.getMonth(); // 월
date.getHours() // 시
date.getMinutes() // 분
date.getSeconds() // 초
  • 이외에 더 많은 프로퍼티를 존재 한다.
const clockContainer = document.querySelector(".js-clock"),
      clockTitle     = clockContainer.querySelector("h1");

function getTime() {
    const date = new Date();  // Date 객체 생성
    const minutes = date.getMinutes(); // "분" 값을 반환
    const hours = date.getHours();     // "시" 값을 반환
    const seconds = date.getSeconds(); // "초" 값을 반환
}

function init() {
    getTime();
}

init();
  • 위 코드처럼 Date 객체의 프로퍼티를 사용하여 각 시간 값을 가져왔다.
  • 그럼 이제 부터는 가져온 시간 값을 화면에 표시 해보자.
const clockContainer = document.querySelector(".js-clock"),
      clockTitle     = clockContainer.querySelector("h1");

function getTime() {
    const date = new Date();
    const minutes = date.getMinutes();
    const hours = date.getHours();
    const seconds = date.getSeconds();
    clockTitle.innerText = `${hours}:${minutes}:${seconds}`; 
    // 백틱(`)를 사용하여 각 각 값을 ${} 안에 작성한다. 
    // element.innerText는 각 태그의 텍스트를 수정할 수 있다. 
}

function init() {
    getTime();
}

init();
  • 여기서 문제는 각 시, 분, 초 가 0~9일때 아래처럼 표현이 된다.
  • 그래서 해당 각 시, 분, 초 가 10보다 작으면 숫자 앞에 '0' 붙여서 표시하게 한다.

clockTitle.innerText = `${hours}:${minutes}:${seconds < 10 ? `0${seconds}` : seconds}`;
// 삼항 연사자를 사용하여 조건식을 걸어서 해당 문제를 해결한다. 
  • 해당 조건식을 시,분 에 모두 적용한다.
const clockContainer = document.querySelector(".js-clock"),
      clockTitle     = clockContainer.querySelector("h1");

function getTime() {
    const date = new Date();
    const minutes = date.getMinutes();
    const hours = date.getHours();
    const seconds = date.getSeconds();
    clockTitle.innerText = `${hours < 10 ? `0${hours}` : hours}:${minutes < 10 ? `0${minutes}` : minutes}:${seconds < 10 ? `0${seconds}` : seconds}`;
    
}

function init() {
    getTime();
}

init();
  • 그럼 이제는 화면에 표시된 시간은 지금 새로고침 할때만 다시 시간을 받아서 표시가 되는데
    해당 시간을 1초마다 업데이트되어 화면에 표시 되게 할 것입니다.
  • setInterval() 메서드
  • setInerval(호출되는함수, 해당 주기마다 호출되는 기준(단위:ms))
  • setInerval(function, 1000) // 1초마다 함수 호출
const clockContainer = document.querySelector(".js-clock"),
      clockTitle     = clockContainer.querySelector("h1");

function getTime() {
    const date = new Date();
    const minutes = date.getMinutes();
    const hours = date.getHours();
    const seconds = date.getSeconds();
    clockTitle.innerText = `${hours < 10 ? `0${hours}` : hours}:${minutes < 10 ? `0${minutes}` : minutes}:${seconds < 10 ? `0${seconds}` : seconds}`;
    
}

function init() {
    getTime();
    setInterval(getTime, 1000); // 1초마다 getTime 함수를 호출해서 시간을 업데이트 한다.
}

init();
  • 정리:
  1. document.querySelector() 를 사용하여 html 태그 정보를 가져온다.
  2. init() 함수를 정의하여 각 함수들이 init() 함수 내부에서 호출하는 코드를 작성한다.
  3. Date 객체의 프로퍼티를 사용하여 각 날짜와 시간 정보를 가져온다.
  4. innerText 프로퍼티를 사용하여 가져온 시간을 화면에 표시한다.
  5. (백틱)을 사용하여 시간 값을 innerText 프로퍼티에 할당한다.
  6. setInterval() 함수를 이용하여 해당 시간 주기마다 함수를 호출하여 시간을 업데이트 한다.
  • 코드 실행 순서 :
  1. 변수 clockContainer, clockTitle의 html 태그 정보를 가져와 할당. (document 객체의 프로퍼 사용)
  2. init() 함수 실행.
  3. getTime() 함수 실행.
  4. Date 객체 생성.
  5. Date 객체의 프로퍼티를 사용하여 변수 minutes, hours, seconds에 각 각 값을 할당.
  6. clockTitle.innerText에 변수 minutes, hours, seconds 값을 할당.
  7. setInterval(getTime, 1000) 함수 실행.

2.gretting.js

  • 화면에서 데이터를 입력(form 태그 사용)
  • 입력한 데이터를 화면에 다시 표시
  • 브라우저를 닫고 다시 열어도 데이터 유지


  • 데이터를 입력할 태그 작성
  • 입력한 데이터를 화면에 표시할 태그 작성
  • HTML
<form class="js-form form">
        <input type="text" placeholder="What is your name?"/>
</form>
<h4 class="js-greetings greetings"></h4>
  • html의 태그 정보 가져오기.
  • document.querySelector() 사용해서 가져온다.
  • javasript
const form = document.querySelector(".js-form"), // form 태그
      input = form.querySelector("input"),       // input 태그 (데이터 입력용)
      greeting = document.querySelector(".js-greetings"); // h4 태그 (데이터 출력용)
  • init() 함수 선언.
  • localStorage 를 사용하여 해당 값이 있으면 화면에 바로 출력
    값이 없으면 form 태그를 이용하여 값 입력하는 함수 선언 (loadName())
  • 상수를 선언하여 localStorage의 "key"의 데이터를 선언
  • localStorage 란(링크에 설명 참조)
const form = document.querySelector(".js-form"),
      input = form.querySelector("input"),
      greeting = document.querySelector(".js-greetings");
      
const USER_LS = "currentUser"; // 로컬스토리지의 "key"의 데이터 선언
      
function loadName() {
    const currentUser = localStorage.getItem(USER_LS); 
    // 로컬스토리지의 "key"가 있으면 해당 값을 가져와서 변수에 할당, 해당 "key"가 없으면 null 반환하여 변수에 할당.
    
    if(currentUser === null) {
        // 로컬스토리지에 "key"가 없을때 form 태그 사용하여 데이터 입력.
    } else {
        // 로컬그토리지에 "key"가 있을때 해당 value를 가져와 화면에 출력.
    }
}

function init() {
    loadName(); 
}

init();      
  • css
  • form 태그와 h4 태그는 default 설정으로 화면이 출력이 안된다.
.form,
.greetings {
    display: none;
}

.showing {
    display: block;
}
  • currentUser === null 일때, 즉 로컬스토리지에 데이터가 없을때
    form 태그를 입력하여 해당 데이터를 화면에 출력후
    로컬스토리지에 데이터 저장
  • askForName() : form 태그 화면에 표시후 form태그 이벤트 발생 함수 실행.
  • handleSubmit() : form 태그 데이터 입력후 enter(submit)시 함수 실행.
  • paintGreeting() : form 태그 화면 출력 X, h4 태그 화면 출력 O, h4 태그의 form태그의 입력된 값을 텍스트로 할당 하는 기능.
  • saveName() : form 태그에 입력한 값을 localStorage에 저장.
const form = document.querySelector(".js-form"),
      input = form.querySelector("input"),
      greeting = document.querySelector(".js-greetings");

const USER_LS = "currentUser",
    SHOWING_CN = "showing";

function saveName(text) {
    localStorage.setItem(USER_LS, text);
}

function handleSubmit(event) {
    event.preventDefault(); // submit 이벤트 발생시 page reload가 되므로 해당 reload 기능을 막는 역활.
    const currentValue = input.value; // currentValue 변수에 form태그의 입력한 값을 할당.
    console.log(currentValue);
    paintGreeting(currentValue); // 변수를 매개변수로 넘기면서 해당 form태그 입력값을 화면 출력하는 기능을 하는 함수 실행.
    saveName(currentValue); // 로컬스토리지에 form태그의 입력한 값을 저장.
}

function askForName() {
    form.classList.add(SHOWING_CN); // form태그의 클래스를추가하여 스타일 수정(화면 출력)
    form.addEventListener("submit", handleSubmit); // form 태그 데이터 입력후 enter(submit)시 이벤트 발생으로 handleSubmit() 함수 실행.
}

function paintGreeting(text) {
    form.classList.remove(SHOWING_CN); // form 태그의 해당 클래스 제거(화면 출력 x)
    greeting.classList.add(SHOWING_CN); // h4 태그의 해당 클래스 추가(화면 출력 o)
    greeting.innerText = `Hello ${text}`; // h4 태그의 매개변수 넘겨온 값(입력값)을 h4 태그의 텍스트로 추가.
}

function loadName() {
    const currentUser = localStorage.getItem(USER_LS);
    if(currentUser === null) {
        askForName(); // 로컬스토리지에 데이터가 없을때 실행.
    } else {
    	
    }
}

function init() {
    loadName();
}

init();
  • 로컬스토리지에 해당 데이터가 있을시엔 form 태그 화면에 출력안하고 해당 데이터를 h4 태그의 텍스트로 추가
const form = document.querySelector(".js-form"),
      input = form.querySelector("input"),
      greeting = document.querySelector(".js-greetings");

const USER_LS = "currentUser",
    SHOWING_CN = "showing";

function saveName(text) {
    localStorage.setItem(USER_LS, text);
}

function handleSubmit(event) {
    event.preventDefault(); // 이벤트의 기본동작을 막기 위해
    const currentValue = input.value;
    console.log(currentValue);
    paintGreeting(currentValue);
    saveName(currentValue);
}

function askForName() {
    form.classList.add(SHOWING_CN);
    form.addEventListener("submit", handleSubmit);
}

function paintGreeting(text) {
    form.classList.remove(SHOWING_CN);
    greeting.classList.add(SHOWING_CN);
    greeting.innerText = `Hello ${text}`;
}

function loadName() {
    const currentUser = localStorage.getItem(USER_LS);
    if(currentUser === null) {
        askForName();
    } else {
        paintGreeting(currentUser); // 로컬스토리지에 해당 데이터가 있을시엔 함수 실행.
    }
}

function init() {
    loadName();
}

init();
  • 정리 :
  1. form 태그를 이용하여 입력한 값을 화면 출력한다.
  2. 해당 값을 localStorage에 저장해서 해당 브라우저를 새로고침하여도 저장소에 데이터가 있으면 해당 값을 가져와 화면 출력한다.
  • 코드 실행 순서:
  1. 변수 form, input, greetin에 html 태그 정보 할당.
  2. 상수 USER_LS, SHOWING_CN에 각각 값 할당.
  3. init() 함수 실행.
  4. loadName() 함수 실행.
  5. 변수 currentUser에 값 할당.
  • currentUser === null 이면
    1. askForName() 함수 실행.
    1. form 태그에 클래스 추가.
    2. form 태그 submit시 handleSubmit() 함수 실행.
    3. 변수 currentValue에 form 태그 입력 값 할당.
    4. paintGreeting() 함수 실행.
    5. form 태그 해당 클래스 제거.
    6. h4 태그 해당 클래스 추가.
    7. h4 태그에 form 값을 텍스트로 추가.
  • currentUser === null 아니면
    1. paintGreeting() 함수 실행.
    1. form 태그 해당 클래스 제거.
    2. h4 태그 해당 클래스 추가.
    3. h4 태그에 form 값(localStorage의 데이터)을 텍스트로 추가.

3.todo.js

  • form 태그에 데이터 입력시 해당 데이터를 화면 출력
  • 해당 데이터를 버튼 클릭으로 삭제 가능.
  • 브라우저 새로고침하여도 로컬스토리지에 해당 데이터가 있을시에
    별도의 데이터 입력 과정없이 해당 데이터를 가져와 화면 출력.

  • form 태그에 데이터 입력.
  • ul 태그에 form태그에 입력된 데이터를 표시.
  • html
<form class="js-toDoForm">
        <input type="text" placeholder="write a to do"/>
</form>
<ul class="js-toDoList">
</ul>
  • html의 태그 정보 가져오기(form 태그, ul 태그)
  • 가져온 태그 정보를 변수에 할당.
const toDoform = document.querySelector(".js-toDoForm"), // form 태그
    toDoInput = toDoform.querySelector("input"),         // input 태그
    toDoList = document.querySelector(".js-toDoList");   // ul 태그
  • init() 함수 선언
  • 로컬스토리지에서 toDo 데이터가 있을경우 해당 데이터를 가져오는 기능(loadToDos() 함수)
  • form 태그에 데이터 입력후 enter 입력하면 이벤트 발생
const toDoform = document.querySelector(".js-toDoForm"),
    toDoInput = toDoform.querySelector("input"),
    toDoList = document.querySelector(".js-toDoList");

function init() {
    loadToDos(); // 로컬스토리지에서 데이터 가져오기
    toDoform.addEventListener("submit", handleSubmit); // form 태그 데이터 입력 후 enter 입력시 이벤트 발생
}

init();
  • form 태그 데이터 입력후 submit(enter 입력)시 handleSubmit() 함수 실행
const toDoform = document.querySelector(".js-toDoForm"),
    toDoInput = toDoform.querySelector("input"),
    toDoList = document.querySelector(".js-toDoList");
    
function handleSubmit(event) {
    event.preventDefault(); // form 태그 submit 시 페이지 reload 방지
    const currentValue = toDoInput.value; // 입력한 데이터를 변수에 할당.
    paintToDo(currentValue); // 해당 데이터를 화면 출력 기능 함수 실행
    toDoInput.value = ""; // form 태그의 input태그 입력한 텍스트 초기화 기능
}

function init() {
    loadToDos();
    toDoform.addEventListener("submit", handleSubmit);
}

init();
  • paintToDo() 함수 :
    • 입력한 데이터(form 태그)를 화면 출력 기능
    • 해당 데이터를 로컬스토리지에 저장 하는 함수(saveToDos) 실행.
    • 화면에 출력된 데이터의 삭제 버튼 클릭시 해당 지워지는 이벤트 함수 실행.
const toDoform = document.querySelector(".js-toDoForm"),
    toDoInput = toDoform.querySelector("input"),
    toDoList = document.querySelector(".js-toDoList");
    
let toDos = []; // form 태그에서 입력한 데이터를 해당 배열에 저장.
    
function paintToDo(text) {
    const li = document.createElement("li"); // li 태그를 동적으로 생성후 변수 li 할당.
    const delBtn = document.createElement("button"); // button 태그 동적 생성후 변수 delBtn 할당.
    const span = document.createElement("span"); // span 태그 동적 생성후 변수 span 할당.
    const newId = toDos.length + 1; // 입력한데이터를 저장할때 해당 데이터의 특정 id를 부여하여 한다, 
    // 나중에 해당 데이터를 객체로 할당할때 key 나 해당 화면에 표시 될때 해당 태그의 id 값을 부여할때 사용 된다.
    // toDos.length + 1 이유: 해당 id룰 부여할때는 해당 배열에 데이터를 할당하기 전이므로 해당 배열에 데이터가 없을땐 길이가 0이므로 +1를 해준다.
    
    delBtn.innerText = "X"; // 삭제 버튼 텍스트 추가
    delBtn.addEventListener("click", deleteToDo); // 삭제버튼 클릭시 이벤트 발생 deleteToDo() 함수 실행
    span.innerText = text; // span 태그의 입력한 태그 데이터 텍스트로 추가
    li.appendChild(delBtn); // 이전에 만든 li태그의 자식요소로 button 태그 추가
    li.appendChild(span); // li태그의 자식요소로 span 태그 추가
    li.id = newId; // li태그의 id 속성의 newId 값 할당.
    toDoList.appendChild(li); // ul 태그의 자식요소로 li 태그 추가
    const toDoObj = {
        text : text,
        id : newId
    } // 객체를 선언하고 입력한 데이터와 id를 프로퍼티로 할당.
    toDos.push(toDoObj); // 해당 객체를 배열에 할당.
    saveToDos(); // 로컬스토리지에 저장하는 기능(함수 실행.) 
}
    
function handleSubmit(event) {
    event.preventDefault(); 
    const currentValue = toDoInput.value; 
    paintToDo(currentValue); 
    toDoInput.value = ""; 
}

function init() {
    loadToDos();
    toDoform.addEventListener("submit", handleSubmit);
}

init();
  • saveToDos() :
    • 입력한 데이터를 로컬스토리지에 저장.
  • 로컬스토리지에 저장하는 데이터는 "key" : "value" 형식으로 그리고 데이터 타입은 무조건 String 으로 저장된다.
  • 그래서 입력한 데이터는 객체로 저장이 되었기때문에 해당 객체를 String 타입으로 변환을 해주어야 한다.
  • 이때 사용하는 함수는 JSON.stringify() 이다.
  • toDos 출력

    console.log(toDos);
    (9) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
    0: {text: "ㅁㄴㅇ", id: 1}
    1: {text: "ㅁㄴㅇㄹ", id: 2}
    2: {text: "ㅁㄴㅇㄹ", id: 3}
    3: {text: "ㅁㄴㅇㄹ", id: 4}
    4: {text: "ㅁㄴㅇㄹ", id: 5}
    5: {text: "ㅁㄴㅇㄹ", id: 6}
    6: {text: "ㅁㄴㅇㄹ", id: 7}
    7: {text: "ㅁㄴㅇㄹ", id: 8}
    8: {text: "ㅁㄴㅇㄹ", id: 9}

  • JSON.stringify(toDos) 출력

[{"text":"ㅁㄴㅇ","id":1},{"text":"ㅁㄴㅇㄹ","id":2},{"text":"ㅁㄴㅇㄹ","id":3},{"text":"ㅁㄴㅇㄹ","id":4},{"text":"ㅁㄴㅇㄹ","id":5},{"text":"ㅁㄴㅇㄹ","id":6},{"text":"ㅁㄴㅇㄹ","id":7},{"text":"ㅁㄴㅇㄹ","id":8},{"text":"ㅁㄴㅇㄹ","id":9}]

  • 해당 객체의 프로퍼티의 타입을 String 타입으로 변환.
const toDoform = document.querySelector(".js-toDoForm"),
    toDoInput = toDoform.querySelector("input"),
    toDoList = document.querySelector(".js-toDoList");

const TODOS_LS = 'toDos'; // 로컬스토로지에 어떤 데이터를 저장할때 해당 "key"로 할당된다. 
                          // 해당 데이터는 변하지 않으므로 상수로 선언.

let toDos = [];

function saveToDos() {
    localStorage.setItem(TODOS_LS, JSON.stringify(toDos)); 
    // 로컬스토리지 데이터 저장
    // 해당 데이터는 객체이므로 로컬스토리지는 String 타입만 저장 가능
    // 그래서 JSON.stringify()를 이용하여 객체를 String 타입으로 변환하여 저장.
}   


function paintToDo(text) {
    // console.log(text);
    const li = document.createElement("li");
    const delBtn = document.createElement("button");
    const span = document.createElement("span");
    const newId = toDos.length + 1;
    delBtn.innerText = "X";
    delBtn.addEventListener("click", deleteToDo);
    span.innerText = text;
    li.appendChild(delBtn);
    li.appendChild(span);
    li.id = newId;
    toDoList.appendChild(li);
    const toDoObj = {
        text : text,
        id : newId
    }
    toDos.push(toDoObj);
    saveToDos();
}

function handleSubmit(event) {
    event.preventDefault();
    const currentValue = toDoInput.value;
    paintToDo(currentValue);
    toDoInput.value = "";
}

function init() {
    loadToDos();
    toDoform.addEventListener("submit", handleSubmit);
}

init();
  • deleteToDo() 함수 :
    • 화면에 표시는 리스트 데이터를 삭제하는 기능
    • 해당 데이터를 삭제할때 로컬스토리지에 저장되어있는 데이터도 삭제.
  • delBtn.addEventListener("click", deleteToDo);
  • function deleteToDo(event) {}
  • 해당 함수에서 인자로 넘겨온 event는 어떤 정보가 있는가?!
  • 해당 클릭한 button에 관련된 정보 등등 클릭에 관한 정보를 담고 있다.
  • Array.filter(함수) 메서드
  • 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환합니다.
const toDoform = document.querySelector(".js-toDoForm"),
    toDoInput = toDoform.querySelector("input"),
    toDoList = document.querySelector(".js-toDoList");

const TODOS_LS = 'toDos';

let toDos = [];

function deleteToDo(event) {
    const btn = event.target; // event.target에는 클릭한 버튼의 태그 관련 정보를 변수 btn에 할당한다.
    const li = btn.parentNode; // 해당 태그정보의 부모요소인 li태그의 정보를 가져와 변수 li에 할당한다.
    toDoList.removeChild(li); // ul태그의 자식요소중에서 이전에 반환했던 li태그를 제거한다.
    const cleanToDos = toDos.filter(function(toDo) { // 매개변수 toDo는 toDos 배열에서 0, 1, 2, .. 각각 인덱스의 값을 의미한다.
        return toDo.id !== parseInt(li.id); // 해당 배열의 id 값이랑 li 태그의 값이 같지 않은것 만 반환한다. 
        // 해당 로직은 클릭한 버튼의 li태그만 제외하고 나머지만 반환하여 다시 배열을 생성하기위해.
        // parseInt() 는 어떠한 데이터 타입을 숫자형으로 타입을 변환한다.
    });
    
    toDos = cleanToDos; // 반환된 배열을 다시 toDos 배열에 할당한다.
    saveToDos(); // 삭제된 데이터를 제외하고 다시 로컬스토리지에 저장한다.
}

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

function paintToDo(text) {
    const li = document.createElement("li");
    const delBtn = document.createElement("button");
    const span = document.createElement("span");
    const newId = toDos.length + 1;
    delBtn.innerText = "X";
    delBtn.addEventListener("click", deleteToDo);
    span.innerText = text;
    li.appendChild(delBtn);
    li.appendChild(span);
    li.id = newId;
    toDoList.appendChild(li);
    const toDoObj = {
        text : text,
        id : newId
    }
    toDos.push(toDoObj);
    saveToDos();
}

function handleSubmit(event) {
    event.preventDefault();
    const currentValue = toDoInput.value;
    paintToDo(currentValue);
    toDoInput.value = "";
}

function init() {
    loadToDos();
    toDoform.addEventListener("submit", handleSubmit);
}

init();
  • loadToDos() 함수 :
  • 로컬스토리지 해당데이터가 있을 경우 화면 출력.
const toDoform = document.querySelector(".js-toDoForm"),
    toDoInput = toDoform.querySelector("input"),
    toDoList = document.querySelector(".js-toDoList");

const TODOS_LS = 'toDos';

let toDos = [];


function deleteToDo(event) {
    const btn = event.target;
    const li = btn.parentNode;
    toDoList.removeChild(li);
    const cleanToDos = toDos.filter(function(toDo) {
        return toDo.id !== parseInt(li.id); //toDo.id 는 숫자 / li.id 는 string
    });

    toDos = cleanToDos;
    saveToDos();
    
    console.log(cleanToDos);
}

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

function paintToDo(text) {
    const li = document.createElement("li");
    const delBtn = document.createElement("button");
    const span = document.createElement("span");
    const newId = toDos.length + 1;
    delBtn.innerText = "X";
    delBtn.addEventListener("click", deleteToDo);
    span.innerText = text;
    li.appendChild(delBtn);
    li.appendChild(span);
    li.id = newId;
    toDoList.appendChild(li);
    const toDoObj = {
        text : text,
        id : newId
    }
    toDos.push(toDoObj);
    saveToDos();
}

function handleSubmit(event) {
    event.preventDefault();
    const currentValue = toDoInput.value;
    paintToDo(currentValue);
    toDoInput.value = "";
}

function loadToDos() {
    const loadedToDos = localStorage.getItem(TODOS_LS); // 해당 데이터가 있으면 가져와서 변수에 할당. ( key : TODOS_LS('toDos') )
    if (loadedToDos !== null) { // 해당 key에대한 데이터가 있으면 조건문 블럭 실행.
        const parsedToDos = JSON.parse(loadedToDos); // 로컬스토리지에 있는 데이터는 String 타입이므로 해당 타입을 JSON 타입으로 변환후 변수에 할당.
        parsedToDos.forEach(function(toDo) { // 배열의 forEach 메서드를 이용하여 해당 각각 배열의 각 인덱스별 값마다 반복문 실행.
            paintToDo(toDo.text); // 각 인덱스의 데이터를 화면에 출력 기능 함수 실행.
        });


    }

}


function init() {
    loadToDos();
    toDoform.addEventListener("submit", handleSubmit);
}

init();
  • 정리 :
  1. form 태그의 입력된 데이터를 화면에 출력
  2. 해당 데이터를 로컬스토리지에 저장.
  3. 화면 출력된 데이터를 삭제 버튼 클릭시.
  4. 화명 출력된 데이터 제거 및 로컬스토리지에 저장된 데이터 삭제.
  5. form 태그에 데이터 입력 전에 로컬스토리지에 해당 데이터가 존재하면.
  6. 해당 데이터를 가져와 화면에 출력.
  • 코드 실행 순서:
  1. 각 변수 toDoform, toDoInput, toDoList에 태그 정보 할당.
  2. 상수 TODOS_LS 선언 및 배열 toDos 선언
  3. init() 함수 실행.
  4. loadToDos() 함수 실행.
  5. 변수 loadedToDos에 로컬스토리지에 데이터를 가져와 할당.
  6. 해당 데이터가 존재하면 변수 parsedToDos에 로컬스토리지에 데이터를 할당.
  7. paintToDo() 함수 실행. 각 데이터를 화면 출력.
  8. form 태그 데이터 입력후 enter 입력시 toDoform.addEventListener("submit", handleSubmit) 이벤트 발생.
  9. handleSubmit() 함수 실행.
  10. paintToDo(currentValue) 함수 실행. 입력한 데이터를 매개변수로 넘긴다.
  11. 변수 li, delBtn, span에 동적으로 태그를 생성하여 할당.
  12. 해당 변수에 각 텍스트 및 정보 할당.
  13. 각 만든 태그들을 li태그의 자식요소 할당.
  14. 입력한 데이터를 객체 toDoObj로 할당.
  15. 배열 toDos에 해당 객체를 추가.
  16. 해당 배열 데이터를 로컬스토리지에 저장. saveToDos() 함수 실행.
  17. 해당 리스트에서 삭제 버튼 클릭시. delBtn.addEventListener("click", deleteToDo) 이벤트 발생.
  18. deleteToDo() 함수 실행.
  19. toDoList.removeChild(li). 화면에 출력된 해당 데이터 li태그 제거.
  20. 로컬스토리지의 해당 데이터 삭제.
const cleanToDos = toDos.filter(function(toDo) {
        return toDo.id !== parseInt(li.id); //toDo.id 는 숫자 / li.id 는 string
    });
    toDos = cleanToDos;
    saveToDos();

4.weather.js

  • API를 사용하여 위치정보와 온도 정보를 가져와 화면에 출력.
  • fetch() 함수 :
    • API를 사용하기 위해 사용되는 함수.
    • fetch(url) : 해당 API URL를 매개변수로 넘겨서 사용 하면된다.
  • then() 함수 :
    • 어떤함수가 실행되고 반환, 즉, 반응(성공)하면 response 반환?!
    • 사실 잘 모르겠습니다. 아직은...
<span class="js-weather"></span>
  • javascript
const weather = document.querySelector(".js-weather");


const API_KEY = "30c7f1237edbc15183af0aa893d8a5c5"; // 해당 API를 사용하기위한 문자열을 변수에 할당.
const COORDS = 'coords'; // 로컬스토리지에 저장되는 "KEY" 값 상수에 할당.

// API를 사용하여 온도, 위치 정보를 받아와 화면에 출력 기능
function getWeather(lat, long) {
    fetch(
        `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${long}&appid=${API_KEY}&units=metric`
    ).then(function(response) {
        return response.json();
    }).then(function(json) {
        console.log(json);
        const temperature = json.main.temp;
        const place = json.name;
        weather.innerText = `${temperature} @ ${place}`;
    });
}

// 온도, 위치 정보를 로컬스토리지에 저장 기능
function saveCoords(coordsObj) {
    localStorage.setItem(COORDS, JSON.stringify(coordsObj));
}

// 가져온 위치정보를 바탕으로 API 실행 함수에 매개변수로 전달. (위도,경도)
function handleGeoSucces(position) {
    console.log(position);
    const latitude = position.coords.latitude;
    const longitude = position.coords.longitude;
    const coordsObj = {
        latitude,
        longitude
    } // latitude == latitude / longitude == longitude

    saveCoords(coordsObj);
    getWeather(latitude, longitude);
}

// 위치정보를 가져오지 못했을때 console.log로 오류 메세지 출력.
function handleGeoError() {
    console.log("cant access geo location");
}

// 자바스크립트의 내장객체인 navgiator를 해당 위치정보를 가져와 해당 함수 실행.
function askForCoords() {
    navigator.geolocation.getCurrentPosition(handleGeoSucces, handleGeoError);
}

// 로컬스토리지에 데이터가 있을땐 해당 정보 화면에 출력.
// 없으면 각 함수를 실행하여 해당 정보를 가져오고 화면 출력하는 함수 실행.
function loadCoords() {
    const loadedCoords = localStorage.getItem(COORDS);
    if(loadedCoords === null) {
        askForCoords();
    } else {
        const parseCoords = JSON.parse(loadedCoords);
        getWeather(parseCoords.latitude, parseCoords.longitude);
    }
}

function init() {
    loadCoords()
}

init();
  • 출력 화면.

5.bg.js

  • 새로고침 할때마다 배경화면 변경
  • 해당 변경되는 이미지는 해당 폴더에 위치함.
  • body 태그 정보를 가져와 변수에 할당.

const body = document.querySelector("body"); // body 태그정보를 해당 변수에 할당.
  • init() 함수 선언.
  • 해당 이미지를 불러올때 랜덤하게 불러오게 하기위해 해당 번호를 저장하는 변수 선언.
  • 배경이미지를 출력하는 함수 실행.
const body = document.querySelector("body");

function init() {
    const randomNumber = getnRandom(); // getnRandom() 함수의 반환값을 변수randomNumber 할당.
    paintImage(randomNumber); // 해당 변수 randomNumber(이미지 이름:숫자)를 매개변수로 넘겨 화면에 이미지를 출력하는 함수 실행. 
}

init();
  • getnRandom() :
    • 이미지 숫자를 랜점하게 출력하는 함수
const body = document.querySelector("body");

const IMG_NUMBER = 6; // 이미지 갯수를 상수로 선언하여 할당.

function getnRandom() {
    const number = Math.floor(Math.random() * IMG_NUMBER);
    // IMG_NUMBER : 이미지의 총 갯수를.
    // Math.random() : 내장객체의 함수를 사용하여 random하게 숫자 출력
    // Math.floor(Math.random()) : 소수점자리수를 버림.
    // Math.floor(Math.random() * IMG_NUMBER) : 출력되는 숫자의 범위 지정.
    
    return number; // 해당 값을 반환.
}

function init() {
    const randomNumber = getnRandom();
    paintImage(randomNumber);
}

init();
  • 해당 랜덤하게 출력된 숫자(이미지 번호)를 기준으로 해당 이미지를 화면 출력
  • paintImage() 함수
const body = document.querySelector("body");

const IMG_NUMBER = 6;

function paintImage(imgNumber) {
    const image = new Image(); // 이미지 객체 생성
    image.src = `images/${imgNumber + 1}.jpg`; // 이미지를 불러오기 위해 해당 src에 해당 경로 할당. 
    // imgNumber + 1 이유 : 해당 숫자는 0부터 시작이여서 해당 숫자에 +1를 한다.
    image.classList.add("bgImage"); // 해당 이미지에 클래스를 추가하여 css 스타일 추가
    body.prepend(image); // 해당 body태그의 시작부분에 이미지 객체 추가. 
    // append : 해당 요소의 끝부분에 추가
}

function getnRandom() {
    const number = Math.floor(Math.random() * IMG_NUMBER);
    return number;
}

function init() {
    const randomNumber = getnRandom();
    paintImage(randomNumber);
}

init();
  • 정리 :
  1. body 태그의 정보를 변수 할당.
  2. 숫자를 랜덤하게 생성.
  3. 해당 생성한 숫자를 사용하여 이미지 선택.
  4. 해당 이미지를 body 태그에 추가.
  • 코드 실행 순서 :
  1. 변수 body 에 body 태그 정보를 할당.
  2. 상수 IMG_NUMBER에 총 이미지 갯수 할당.
  3. init() 함수 실행.
  4. getnRandom() 함수 실행.
  5. 숫자 랜덤하게 생성하여 변수 number에 할당.
  6. 반환된 number를 변수 randomNumber에 할당.
  7. paintImage(randomNumber) 함수 실행.
  8. image 객체 생성.
  9. 이미지 경로 지정. 지정할때 해당 넘어온 변수 randomNumber를 기준으로 할당.
  10. body 태그에 해당 이미지객체를 추가.
  11. 새로고침할때마다 화면 이미지 변경.

참조사이트 :
https://nomadcoders.co/javascript-for-beginners/lectures/1471
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

profile
ENJOY!! PROGRAMING!!

0개의 댓글