🍠 바닐라 JS로 크롬 앱 만들기 : 노마드 코더 클론 코딩 강의 🍠

2023. 7. 10. 02:09개발/🍠 바닐라JS 노마드 코더 클론코딩

 

 

 

우히히

 

 

 

강의 필기한 거

 

 

MOMENTUM

 

 

코드 짠 거

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8" />
    <meta http-equiv="X-UA-Compatible" content = "IE=edge" />
    <meta name = "viewport" content="width=device-width", initial-scale="1.0" />
    <link rel = "stylesheet" href="css/style.css">
    <title>Momentum</title>
</head>
<body>
    <h2 id = "clock">00:00:00</h2>
    <form id = "login-form" class = "hidden">
        <input 
            required
            maxlength = "15"
            type = "text" 
            placeholder="What is your name?"
        />
        <input type = "submit" value = "Log In" />
    </form>
    <h1 id = "greeting" class = "hidden"></h1>
    <form id = "todo-form">
        <input type = "text" placeholder ="Write a To do and Press Enter" required/>
    </form>
    <ul id="todo-list"></ul>
    <div id = "quote">
        <span></span>
        <span></span>
    </div>
    <div id ="weather">
        <span></span>
        <span></span>
    </div>
    <script src = "js/greeting.js"></script>
    <script src = "js/clock.js"></script>
    <script src = "js/quotes.js"></script>
    <script src = "js/background.js"></script>
    <script src = "js/todo.js"></script>
    <script src = "js/weather.js"></script>
</body>
</html>

 

.hidden{
    display: none;
}


img{
    position:absolute;
    width: 100%;
    height: 100%;
    left: 0px;
    top: 0px;
    right: 0px;
    bottom: 0px;
    z-index: -1;
    opacity: 80%;
}

 

const loginForm = document.querySelector("#login-form"); //document에서 id : login-form인 element 찾아서 저장
const loginInput = loginForm.querySelector("input"); //loginForm에서 input element 찾아서 저장

const greeting = document.querySelector("#greeting"); //document에서 id : greeting인 element 찾아서 저장
//반복되는 string 변수로 묶어서 저장 -> 변수명은 대문자로
const HIDDEN_CLASSNAME = "hidden";
const USERNAME_KEY = "username";

function onLoginSubmit(event){
    event.preventDefault(); //submit의 디폴트 동작(새로고침) 막기 
    const username = loginInput.value; //변수 username에 loginInput의 value(입력된 값) 저장
    localStorage.setItem(USERNAME_KEY, username); //local Storage에 username 저장
    loginForm.classList.add(HIDDEN_CLASSNAME); //loginForm의 class에 hidden(CSS) 추가
    paintGreetings(username);
}

function paintGreetings(username){
    greeting.classList.remove(HIDDEN_CLASSNAME);
    greeting.innerText = `Hello ${username}`;
}

const savedUsername = localStorage.getItem(USERNAME_KEY);
if (savedUsername == null){
    loginForm.classList.remove(HIDDEN_CLASSNAME);
    loginForm.addEventListener("submit", onLoginSubmit); //submit하면 onLoginSubmit 함수 실행(object에 방금 실행한 동작 정보 매개변수 형식으로 담아서)
} else{
    paintGreetings(savedUsername);
}
const images = ["1.jpeg", "2.jpeg", "3.jpeg"]; //이미지 array

const chosenImage = images[Math.floor(Math.random()*images.length)]; //이미지 랜덤 선택

const bgImage = document.createElement("img"); //document에 element 추가
bgImage.src = `img/${chosenImage}`; //bgImage 출처 만들기
console.log(bgImage); 
document.body.appendChild(bgImage); //html body에 bgImage 추가
const clock = document.querySelector("h2#clock"); //document에서 h2 중 id : clock 인 element 찾기

function getClock(){
    const date = new Date(); //Date : 현재 날짜와 시간 저장된 객체 생성
    const hours = String(date.getHours()).padStart(2, "0"); //Date에서 시각 가져오기(getHours) -> String으로 type 변환 -> 2자릿수로 고정, 앞에 0으로 채우기(padStart)
    const minutes = String(date.getMinutes()).padStart(2, "0"); //Date에서 분 가져오기(getMinutes) -> String으로 type 변환 -> 2자릿수로 고정, 앞에 0으로 채우기(padStart)
    const seconds = String(date.getSeconds()).padStart(2, "0"); //Date에서 초 가져오기(getSeconds) -> String으로 type 변환 -> 2자릿수로 고정, 앞에 0으로 채우기(padStart)
    clock.innerText = (`${hours}:${minutes}:${seconds}`);
}
getClock();
setInterval(getClock, 1000); //setInterval(a, b) -> b ms마다 a 함수 호출하기
//명언 array
const quotes = [
    {
    quote: 'I never dreamed about success, I worked for it',
    author: 'Estee Lauder',
    },
    {
    quote: 'Do not try to be original, just try to be good.',
    author: 'Paul Rand',
    },
    {
    quote: 'Do not be afraid to give up the good to go for the great',
    author: 'John D. Rockefeller',
    },
    {
    quote: 'If you cannot fly then run. If you cannot run, then walk. And if you cannot walk, then crawl, but whatever you do, you have to keep moving forward.',
    author: 'Martin Luther King Jr.',
    },
    {
    quote: 'Our greatest weakness lies in giving up. The most certain way to succeed is always to try just one more time.',
    author: 'Thomas Edison',
    },
    {
    quote: 'The fastest way to change yourself is to hang out with people who are already the way you want to be',
    author: 'REid Hoffman',
    },
    {
    quote: 'Money is like gasoline during a road trip. You do not want to run out of gas on your trip, but you are not doing a tour of gas stations',
    author: 'Tim O Reilly',
    },
    {
    quote: 'Some people dream of success, while other people get up every morning and make it happen',
    author: 'Wayne Huizenga',
    },
    {
    quote: 'The only thing worse than starting something and falling.. is not starting something',
    author: 'SEth Godin',
    },
    {
    quote: 'If you really want to do something, you will find a way. If you do not, you will find an excuse.',
    author: 'Jim Rohn',
    },
    ];

const quote = document.querySelector("#quote span:first-child"); //document에서 id : quote인 element 중 첫번째 span 찾기
const author = document.querySelector("#quote span:last-child"); //document에서 id : quote인 element 중 마지막 span 찾기
const todaysQuote = quotes[Math.floor(Math.random() * quotes.length)]; //quote 랜덤으로 저장

quote.innerText = todaysQuote.quote; //quote innerText에 대입
author.innerText = todaysQuote.author; //author innerText에 대입
const toDoForm = document.getElementById("todo-form"); //document에서 id:todo-form인 element 찾기
const toDoInput = toDoForm.querySelector("#todo-form input"); //toDoForm에서 id:todo-form인 input 찾기
const toDoList = document.getElementById("todo-list"); //document에서 id:todo-list인 element 찾기

let toDos = []; //toDo 저장해줄 배열

const TODOS_KEY = "todos" //toDos(배열) local Storage에 저장할 때 쓸 KEY값

//ToDoList 저장하기 -> todo 입력, 추가, 삭제 후
function saveToDos(){
    localStorage.setItem(TODOS_KEY, JSON.stringify(toDos)); 
    //local Storage에 toDos 저장
    //local Storage는 배열 저장 못 함(텍스트 형태로 저장됨) -> JSON.stringify 이용해서 배열 스트링으로 변환해서 저장
}

//todo 삭제
function deleteToDo(event){
    const li = event.target.parentElement;
    //누구의 delete button 눌렀는지 찾기 
    //event : 함수 호출할 당시 발생한 동작(click), target : 누구로부터 발생한 동작인지(button), parentElement : 부모 element(button의 parentElement : li)
    toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id));
    //배열에서 특정 item 삭제되는 로직 : 특정 배열 요소 제외하고 '새로운 배열' 생성
    //filter 함수 : 배열의 요소 하나씩 넣어서 filter 처리 (제외할 요소 거르기)
    //li의 id(string이기 때문에 parseInt 사용)가 toDo(toDos의 요소)의 id와 같을 때 true, 다르면 false
    //false 처리된 요소는 배열에서 제외
    saveToDos(); //toDoList 변경 사항(todo 삭제) 저장
    li.remove(); //delete button 누른 li(todo) 삭제
}

//todo 화면에 출력
function paintToDo(newToDo){
    const li = document.createElement("li"); //document에 li element 생성
    li.id = newToDo.id; //li element id newToDo(newToDoObj) id로 초기화
    const span = document.createElement("span"); //document에 span element 생성
    span.innerText = newToDo.text; //span innerText newToDo(newToDoObj) text로 초기화
    const button = document.createElement("button"); //document에 button element 생성
    button.innerText = "X"; //button innerText "X"로 초기화
    button.addEventListener("click", deleteToDo) //버튼 누르면 deleteToDo 호출
    //document에 생성한 elements html에 적절하게 저장
    li.appendChild(span); 
    li.appendChild(button);
    toDoList.appendChild(li);
}

//사용자의 todo 입력 받기
function handleToDoSubmit(event){
    event.preventDefault(); //submit의 디폴트 동작인 새로고침 제어
    const newToDo = toDoInput.value; //입력받은 value값 변수 newToDo에 저장
    //newToDo object 형식으로 저장
    const newToDoObj = {
        text:newToDo, //내용
        id:Date.now(), //특정 todo 찾을 때 사용할 id
    };
    toDos.push(newToDoObj); //배열 toDos에 newToDoObj 삽입
    toDoInput.value = ""; //toDoInput value ""로 초기화 -> enter 누르면 placeholder에 입력되어있는 value 삭제
    paintToDo(newToDoObj); // paintToDo 호출(매개변수 : newToDoObj) 
    saveToDos(); //toDos 변경 사항(새로운 todo 입력) 저장
}

//submit 하면(toDoForm은 html에서 form으로 설정되어 있기 때문에 디폴트 동작이 submit) handleToDoSubmit 호출
toDoForm.addEventListener("submit", handleToDoSubmit);

const savedToDos = localStorage.getItem(TODOS_KEY); //변수 savedToDos에 local Storage에 저장되어있는 toDoList 저장 

//savedToDos가 null이 아닌 경우(저장된 toDoList가 존재)
if(savedToDos!==null){
    const parsedToDos = JSON.parse(savedToDos); 
    //parsedToDos변수에 toDoList '배열' 저장
    //local Storage는 배열 저장 불가, string으로 저장되어 있음
    //JSON.parse를 이용해 스트링 -> 배열
    toDos = parsedToDos; 
    //새로고침 할 때마다 toDos는 빈 배열로 초기화됨(local Storage에는 전에 입력했던 toDoList 존재하지만 toDos는 빈 배열로 초기화되어있음)
    //따라서 toDos를 parsedToDos로 초기화
    //local Storage 와 toDos 구분해줘야 됨
    parsedToDos.forEach(paintToDo);//parsedToDos(배열)의 요소들 각각에 대해 paintToDo 호출
}
const API_KEY ="0c6ddf16a24a928d7a9a6f74908a2bdc";
//성공할 경우 호출
function onGeoOK(position){
    //위치 정보 받기
    const lat = position.coords.latitude;
    const lon = position.coords.longitude;
    //url 정보 - url에 위치 정보, API KEY 삽입
    const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`;
    //API 정보 뽑아와서 html에 띄우기
    fetch(url)
    .then(response => response.json())
    .then(data => {
        const weather = document.querySelector("#weather span:first-child");
        const city = document.querySelector("#weather span:last-child");
        city.innerText = data.name;
        weather.innerText = data.weather[0].main;
    });

}

//error 발생할 경우 호출
function onGeoError(){
    alert("Can't find you. No weather for you.");
}

navigator.geolocation.getCurrentPosition(onGeoOK, onGeoError); //navigator.geolocation 함수(성공할 경우, 에러 뜰 경우)

 

 

 


 

🍠 느낀 점 🍠

 

프론트엔드 처음 경험해봤는데 생각보다 너무 재밌다아...!!

JavaScript도 공부해야 되나...??

DB 공부해서 더 멋들어진 웹사이트 만들어야겠다!

니꼬쌤 너무너무 귀엽다...

 

 

 

 

 

 

 

 

 

 

 

   노마드 코더 회원가입했는데 프로필 사진으로 요놈이 떴다 키키키...

   예전에 고구마 맛탕 먹다가 귀여워서 찍었던 건데 히히

   그래서 이제 니꼬쌤 강의 업로드 할 땐 🍠 요 고구미 쓸 예정 낄낄