gwooden_코린이

자바스크립트 브라우저 기본동작 및 할일목록 만들어보기 본문

프론트엔드/html

자바스크립트 브라우저 기본동작 및 할일목록 만들어보기

gwooden22 2022. 12. 28. 14:20
728x90

1. 브라우저 기본동작

 

- a태그 같은거 클릭하면 -> 해당 페이지로 이동

  폼 전송을 클릭하거나 엔터를 누르면 서버로 전송

  <div>
    <input type="text">
  </div>

   <a href="http://naver.com" onclick=""> 네이버</a>
   <a href="http://google.com" onclick=""> 구글 </a>

 

 

- 기본동작을 막음

   <a href="http://naver.com" onclick="return false"> 네이버</a>
   
   <a href="http://google.com" onclick="event.preventDefault()"> 구글 </a>

See the Pen Untitled by gwooden22 (@gwooden22) on CodePen.

  • return false 보다는 event.preventDefault()를 주로 사용해서 원치않는 동작을 막아줄 수 있다.
  • 폼 전송을 할때 주로 사용한다.

2. 할일목록 만들어보기

 

- HTML

<!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">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>

  <form id="todos">
    <input type="text" placeholder="할일 입력" required>
  </form>

  <ul id="todo-list">
    
  </ul>

    <!-- jQuery -->
    <script src="https://code.jquery.com/jquery-3.6.2.min.js" integrity="sha256-2krYZKh//PcchRtd+H+VyyQoZ/e3EcrkxhM8ycwASPA=" crossorigin="anonymous"></script>
    <script src="script.js"></script>
</body>
</html>

 

- JS

const todos = document.querySelector('#todos');
const todoList = document.querySelector('#todo-list');
const todoInput = todos.querySelector('input');

todos.addEventListener('submit', onSubmit);


function onSubmit(e) {
  e.preventDefault();
  let newTodo = todoInput.value;
  console.log(newTodo);
}

 

See the Pen Untitled by gwooden22 (@gwooden22) on CodePen.


- JS

const todos = document.querySelector('#todos');
const todoList = document.querySelector('#todo-list');
const todoInput = todos.querySelector('input');

todos.addEventListener('submit', onSubmit);


function onSubmit(e) {
  e.preventDefault();
  let newTodo = todoInput.value;
  // console.log(newTodo); 확인용 코드
  todoInput.value = "";

  //아래 printTodo 함수를 onSubmit 함수 내부로 불러와서 연동
  printTodo(newTodo);
}


function printTodo(newTodo) {

  //태그 생성 <li></li>
  const li = document.createElement('li');
  //태그 생성 <span></span>
  const span = document.createElement('span');

  // <li> <span></span> </li>
  li.append(span);

  //<li> <span> newTodo </span> </li>
  span.innerHTML = newTodo;
  todoList.append(li);

  console.log(li);
}


- JS

function printTodo(newTodo) {

  //태그 생성 <li></li>
  const li = document.createElement('li');
  //태그 생성 <span></span>
  const span = document.createElement('span');

  // <li> <span></span> </li>
  li.append(span);

  //<li> <span> newTodo </span> </li>
  span.innerHTML = newTodo;
  todoList.append(li);

  // console.log(li); 확인용 코드
}

See the Pen Untitled by gwooden22 (@gwooden22) on CodePen.

todoList.append(li);

html에 todoList id인 <ul>태그 안에 아래에서 만들어진 li(<li> <span> newTodo </span> </li>) 변수에 담겨있는 값을 넣어줘서 아래 처럼 페이지에 출력되게 된다.

 


- JS

function printTodo(newTodo) {


const data = `<li><span>${newTodo}</span></li>`
todoList.insertAdjacentHTML('beforeend', data);

}

 

See the Pen Untitled by gwooden22 (@gwooden22) on CodePen.


- JS

function printTodo(newTodo) {


const data = `<li>
                <span>
                  ${newTodo} 
                </span>
                 <button>x</button>
              </li>`
todoList.insertAdjacentHTML('beforeend', data);

}

data라는 저장용 변수에 넣고 싶은 태그와 값을 html에 표기하는 것 처럼 넣어주면 추후 추가하고 싶을 태그가 생겼을 때 더욱 간편하다. 그리고 class와 id 추가도 간편하다.

 

또한, 가독성이 개인적으로 첫 번째 방법 보다 좋다.

 

 


const todos = document.querySelector('#todos');
const todoList = document.querySelector('#todo-list');
const todoInput = todos.querySelector('input');

let arr = [];

todos.addEventListener('submit', onSubmit);

function saveTodo() {

  localStorage.setItem('todos', JSON.stringify(arr));

}

todos.addEventListener('submit', onSubmit);


function onSubmit(e) {
  e.preventDefault();
  let newTodo = todoInput.value;

  // console.log(newTodo); 확인용 코드

  //만들어둔 arr 배열방에 입력된 값을 넣어준다.
  arr.push(newTodo);
  saveTodo();

  // console.log(arr); 배열방 확인용 코드
 
  todoInput.value = "";

  //아래 printTodo 함수를 onSubmit 함수 내부로 불러와서 연동
  printTodo(newTodo);
}




/* newTodo 첫번째 방법*/
function printTodo(newTodo) {

  //태그 생성 <li></li>
  const li = document.createElement('li');
  //태그 생성 <span></span>
  const span = document.createElement('span');

  // <li> <span></span> </li>
  li.append(span);

  //<li> <span> newTodo </span> </li>
  span.innerHTML = newTodo;

  const btn = document.createElement('button');
  btn.innerHTML = 'X';
  li.append(btn);

  todoList.append(li);

  // console.log(li); 확인용 코드

  btn.addEventListener('click', deleteTodo)
}




/* newTodo 두번째 방법 */

// function printTodo(newTodo) {


//   const data = `<li>
//                   <span>
//                     ${newTodo} 
//                   </span>
//                   <button>x</button>
//                 </li>`
//   todoList.insertAdjacentHTML('beforeend', data);

//                             (오류)
//   document.querySelectorAll('button')[0].addEventListener('click', deleteTodo);

// }


function deleteTodo(e) {

  // console.log(e.target.parentElement);
  let pn = e.target.parentElement;
  pn.remove();

}


//배열방에 담겨있는 정보를 페이지에 보이도록
//새로고침해도 계속 출력이 되있게
let getTodo = localStorage.getItem('todos');

if(getTodo !== null) {
  let parseTodo = JSON.parse(getTodo);
  // console.log(parseTodo);
  parseTodo.forEach((data) => {
    printTodo(data);
  });
}

입력한 값을 배열방에 담아 브라우저 새로고침을 해도 로컬스토리지에 값이 유지되게 한다.

 

브라우저를 새로고침해도 브라우저 페이지 내에 정보가 계속해서 출력되게 하게끔 로컬스토리지에 있는 정보를 getItem으로 가져온다.

 

제이슨화 되어 있는걸 다시 배열화로 변경해서 forEach로 반복하여 정보 출력 유지

 

 

위 코드에서 문제점으로는 새로고침 후 추가로 값을 입력하면 로컬스토리지에 기존 값은 사라지고 새롭게 입력한 값으로 교체된다.

 


if(getTodo !== null) {
  let parseTodo = JSON.parse(getTodo);
  arr = parseTodo;
  // console.log(parseTodo);
  parseTodo.forEach((data) => {
    printTodo(data);
  });
}

  • arr = parseTodo; 
  • arr 배열 -> 1 ,2 ,3

 

- 순서 돌아보기

1. arr 배열 비어있음

2. 입력 창에 1 입력

3. arr = [1] -> 로컬스토리지로 전송

4. 입력 창에 추가로 정보 입력 2

5. arr = [1, 2] -> 로컬스토리지로 전송 (로컬스토리지로 추가하는 개념이 아닌 업데이트 되는 배열방을 계속해서 덮어씌워준다.)

6. 입력 창에 추가로 정보 입력 3

7. arr = [1, 2, 3] -> 로컬스토리지로 전송

8. 브라우저 새로고침 누르면 arr = [] 초기화

8-1. 초기화 누른후 입력 창에 4 입력

8-2. arr = [4] -> 로컬스토리지로 전송 (arr이 매번 새로고침으로 인해 초기화 되다보니 로컬스토리도 바뀐 배열방 정보를 덮어씌운다.)

9. arr = []

10. parseTodo = 로컬스토리지에 있는게 배열로 보관중

11. arr = 로컬스토리지에 있는게 배열로 보관 (arr = parseTodo)

12. arr = [1, 2, 3]

13. 이제 새로고침 해도 기존꺼 유지한 상태로 푸쉬해서 추가된다.

let getTodo = localStorage.getItem('todos');

if(getTodo !== null) {
  let parseTodo = JSON.parse(getTodo);
  arr = parseTodo;
  // console.log(parseTodo);
  parseTodo.forEach((data) => {
    printTodo(data);
  });
}

새로 고침 하면 위 코드가 제일 먼저 읽힘

 


//값 추가 기능
function onSubmit(e) {
  e.preventDefault();
  let newTodo = todoInput.value;

  // console.log(newTodo); 확인용 코드

  //시리얼 넘버 생성 key, value 생성
  let obj = {
    //key(key, text)와 value(Date.now, newTodo)값이 배열방에 들어가게 된다.
    key : Date.now(),
    text : newTodo,
  }


  //만들어둔 arr 배열방에 입력된 값을 넣어준다.
  arr.push(obj); //기존 newTodo에서 obj로 변경

  saveTodo();

  // console.log(arr); 배열방 확인용 코드
 
  todoInput.value = "";

  //아래 printTodo 함수를 onSubmit 함수 내부로 불러와서 연동
  printTodo(newTodo);
}


/* newTodo 첫번째 방법*/
function printTodo(newTodo) {

  //태그 생성 <li></li>
  const li = document.createElement('li');
  //태그 생성 <span></span>
  const span = document.createElement('span');

  // <li> <span></span> </li>
  li.append(span);

  //<li> <span> newTodo.text </span> </li>
  span.innerHTML = newTodo.text;
  //입력 받아 생성된 <li>태그에 id를 key에 value값인 Date.now()로 생성된 시리얼 넘버를 넣어줘서 고유번호를 새겨주는 의미
  li.id = newTodo.key;

  const btn = document.createElement('button');
  btn.innerHTML = 'X';
  li.append(btn);

  todoList.append(li);

  // console.log(li); 확인용 코드

  btn.addEventListener('click', deleteTodo)
}

key(key, text)와 value(Date.now, newTodo)값이 배열방에 들어가게 된다.

//값 삭제 기능
function deleteTodo(e) {
  
  let pn = e.target.parentElement;
  
  //filter 조건에 만족하는 값만 arr로 넘겨준다. (리턴)
  arr = arr.filter((todo) => todo.key !== pn.id);
  
  pn.remove();

}

filter 함수 : 조건에 만족하는거만 리턴 (해당 함수는 삭제 기능은 따로 없음)

filter((todo) => todo.key !== pn.id);로 arr배열방에 있는걸 todo에 순차적으로 들어가진다.

 

todo => arr[배열방들].key

pn.id = 내가 선택한 특정 배열방

 

비교하며 같지 않은건 제외되고 필터 조건에 만족하는거만 살아남는다.

 

arr = arr.filter((todo) => todo.key !== parseInt(pn.id));

다만, 위 코드에서는 todo.key와 pn.id에 type자체가 String하고 Number이다 보니 타입 자체가 틀려 비교가 안되므로 형변환이 필요하다.

 


const todos = document.querySelector('#todos');
const todoList = document.querySelector('#todo-list');
const todoInput = todos.querySelector('input');

let arr = [];

todos.addEventListener('submit', onSubmit);

function saveTodo() {

  localStorage.setItem('todos', JSON.stringify(arr));

}

todos.addEventListener('submit', onSubmit);


//값 추가 기능
function onSubmit(e) {
  e.preventDefault();
  let newTodo = todoInput.value;

  // console.log(newTodo); 확인용 코드

  //시리얼 넘버 생성 key, value 생성
  let obj = {
    //key(key, text)와 value(Date.now, newTodo)값이 배열방에 들어가게 된다.
    key : Date.now(),
    text : newTodo,
  }


  //만들어둔 arr 배열방에 입력된 값을 넣어준다.
  arr.push(obj); //기존 newTodo에서 obj로 변경

  saveTodo();

  // console.log(arr); 배열방 확인용 코드
 
  todoInput.value = "";

  //아래 printTodo 함수를 onSubmit 함수 내부로 불러와서 연동
  printTodo(obj);
}




/* newTodo 첫번째 방법*/
function printTodo(newTodo) {

  //태그 생성 <li></li>
  const li = document.createElement('li');
  //태그 생성 <span></span>
  const span = document.createElement('span');

  // <li> <span></span> </li>
  li.append(span);

  //<li> <span> newTodo.text </span> </li>
  span.innerHTML = newTodo.text;
  //입력 받아 생성된 <li>태그에 id를 key에 value값인 Date.now()로 생성된 시리얼 넘버를 넣어줘서 고유번호를 새겨주는 의미
  li.id = newTodo.key;

  const btn = document.createElement('button');
  btn.innerHTML = 'X';
  li.append(btn);

  todoList.append(li);

  // console.log(li); 확인용 코드

  btn.addEventListener('click', deleteTodo)
}



/* newTodo 두번째 방법 */

// function printTodo(newTodo) {


//   const data = `<li>
//                   <span>
//                     ${newTodo} 
//                   </span>
//                   <button>x</button>
//                 </li>`
//   todoList.insertAdjacentHTML('beforeend', data);

//                             (오류)
//   document.querySelectorAll('button')[0].addEventListener('click', deleteTodo);

// }



//값 삭제 기능
function deleteTodo(e) {
  
  let pn = e.target.parentElement;
  
  //filter 조건에 만족하는 값만 arr로 넘겨준다. (리턴)
  arr = arr.filter((todo) => todo.key !== parseInt(pn.id));

  //값 추가 기능쪽에서 savaTodo로 저장했지만 값 삭제 기능쪽에서 새롭게 업데이트 되므로 다시 한번 savaTodo();를 넣어준다.
  saveTodo();
  pn.remove();

}



//배열방에 담겨있는 정보를 페이지에 보이도록
//새로고침해도 계속 출력이 되있게
let getTodo = localStorage.getItem('todos');

if(getTodo !== null) {
  let parseTodo = JSON.parse(getTodo);
  arr = parseTodo; // arr = 로컬스토리지에 있는게 배열로 보관
  // console.log(parseTodo);
  parseTodo.forEach((data) => {
    printTodo(data);
  });
}

See the Pen Untitled by gwooden22 (@gwooden22) on CodePen.

728x90
Comments