[Javascript] 이벤트 핸들링 / value속성 이해하기_실습

한효찬·2024년 9월 13일

[공부] Javascript

목록 보기
17/24
post-thumbnail

실습 : https://stackblitz.com/edit/stackblitz-starters-ovnvnm?file=script.js

input창에 글을 입력하면 밑에 트윗 형식으로 글의 리스트가 나오고 좋아요 버튼과 좋아요 개수를 표기할 수 있는 기능이 있는 웹페이지를페이지를 만든다.

1차로 코드를 썼을 때 좋아요 갯수 옆에 undefined가 뜨는 오류가 있었다. 우선 오류 코드 풀이부터 설명 후 어떻게 수정했는지 작성하려고한다.

전체 코드

const tweetInput = document.querySelector('#tweetInput');
const tweetsContainer = document.querySelector('#tweets_container');
const postTweet = document.querySelector('#postTweet');

postTweet.addEventListener('click', function () {
  const tweetsUl = document.createElement('ul');
  if (tweetInput.value === '') {
    alert(`내용을 입력하십시오.`);
    return;
  } else {
    tweetsContainer.append(tweetsUl);
  }

  const tweetsli = document.createElement('li');
  tweetsli.className = 'tweet';
  tweetsli.append(tweetsliContent());
  tweetsUl.append(tweetsli);

  function tweetsliContent() {
    const tweets = document.createElement('p');
    tweets.className = 'tweet-text';
    tweets.textContent = tweetInput.value;

    const likeBtn = document.createElement('button');
    likeBtn.className = 'like-button';
    likeBtn.textContent = `👍`;

    const likeBtnCount = document.createElement('p');
    likeBtnCount.className = 'like-counter';
    likeBtnCount.textContent = '';

    let clickCount = 0;

    likeBtn.addEventListener('click', function () {
      clickCount++;
      likeBtnCount.textContent = clickCount;
    });

    tweetsli.append(tweets, likeBtn, likeBtnCount);
  }
  tweetInput.value = '';
});

전체 코드는 위와 같다. 구간 별로 코드 풀이를 해보려고 한다.

인풋, 제출버튼과 이 요소들이 담긴 컨테이너

const tweetInput = document.querySelector('#tweetInput');
const tweetsContainer = document.querySelector('#tweets_container');
const postTweet = document.querySelector('#postTweet');
  • 인풋, 제출버튼과 이 요소들이 담긴 컨테이너를 변수 선언했다.

제출버튼(postTweet) 클릭 시 이벤트: 인풋창이 빈 문자열 or 뭐 있는 문자열 구분 처리

postTweet.addEventListener('click', function () {
  const tweetsUl = document.createElement('ul');
  if (tweetInput.value === '') {
    alert(`내용을 입력하십시오.`);
    return;
  } else {
    tweetsContainer.append(tweetsUl);
  }
  • postTweet에 이벤트리스너함수를 주고 'click' 시 익명 함수가 나오도록 만들었다.
  • 모든 트윗이 들어갈 tweetUl변수를 선언했다.
  • 만약 tweetInput의 값이 빈 문자열일 경우 alert 경고창 띄우고 return으로 코드 실행을 막았다.(빈 문자열이 트윗에 띄워지지 않도록)
  • 그 반대 경우에는 tweetUl가 tweetsContainer에 추가된다.

제출버튼(postTweet) 클릭 시 이벤트: ul에 들어갈 li 처리

const tweetsli = document.createElement('li');
  tweetsli.className = 'tweet';
  tweetsli.append(tweetsliContent());
  tweetsUl.append(tweetsli);
  • tweetUl에 들어갈 tweetsli 변수 선언했다.
  • tweetsli의 안에 들어갈 내용은 tweetsliContent라는 함수.

제출버튼(postTweet) 클릭 시 이벤트: tweetsliContent 함수의 내용

코드 보기 전에!
li안에 들어갈 내용을 통째로 tweetsliContent라는 함수에 저장했다.
그 이유는 li안에 쓴 글의 내용, 좋아요 버튼, 좋아요 갯수 등 많은 변수와 엘리먼트들이 등장할 예정이라 하나의 함수로 묶어주는 것이 보기에 간편할 것이라고 생각했기 때문이다.

function tweetsliContent() {
    const tweets = document.createElement('p');
    tweets.className = 'tweet-text';
    tweets.textContent = tweetInput.value;

    const likeBtn = document.createElement('button');
    likeBtn.className = 'like-button';
    likeBtn.textContent = `👍`;

    const likeBtnCount = document.createElement('p');
    likeBtnCount.className = 'like-counter';
    likeBtnCount.textContent = '';
  • tweetsliContent 함수 안에 tweetInput에 쓴 글의 내용과 좋아요 버튼, 좋아요 갯수 카운트 변수를 선언했다.
  • likeBtnCount의 경우 likeBtn을 누르기 전에는 아무것도 없는 빈 문자열이여야 하므로 우선적으로 빈 문자열을 대입시켜놨다.

제출버튼(postTweet) 클릭 시 이벤트: likeBtn눌렀을 때 처리

let clickCount = 0;

    likeBtn.addEventListener('click', function () {
      clickCount++;
      likeBtnCount.textContent = clickCount;
    });

    tweetsli.append(tweets, likeBtn, likeBtnCount);
  }
  tweetInput.value = '';
});
  • 우선 clickCount라는 변수를 만들어 0 숫자형을 대입했다.
  • likeBtn을 눌렀을 경우 이벤트 함수를 만들었다.
  • 버튼이 눌릴 때마다 clickCount값이 1씩 증가하도록 만들었다.
  • clickCount의 내용을 likeBtnCount의 텍스트 속성에 재 할당했다.
  • tweetsli에 쓴 글 내용, 좋아요 버튼, 좋아요 갯수 변수들을 추가했다.
  • 모든 작업이 끝나면 tweetInput을 공백으로 비웠다.

'undefined' 오류 수정한 코드

부트캠프 팀원분과 여쭤보아 함께 해결해보았다. (감사합니다..😢)

전체 코드

const tweetInput = document.querySelector('#tweetInput');
const tweetsContainer = document.querySelector('#tweets_container');
const postTweet = document.querySelector('#postTweet');

postTweet.addEventListener('click', function () {
  const tweetsUl = document.createElement('ul');
  if (tweetInput.value === '') {
    alert(`내용을 입력하십시오.`);
    return;
  } else {
    tweetsContainer.append(tweetsUl);
  }

  const tweetsli = document.createElement('li');
  tweetsli.className = 'tweet';
  tweetsUl.append(tweetsli);
  tweetsliContent();

  function tweetsliContent() {
    const tweets = document.createElement('p');
    tweets.className = 'tweet-text';
    tweets.textContent = tweetInput.value;

    const likeBtn = document.createElement('button');
    likeBtn.className = 'like-button';
    likeBtn.textContent = `👍`;

    const likeBtnCount = document.createElement('p');
    likeBtnCount.className = 'like-counter';
    likeBtnCount.textContent = '';

    let clickCount = 0;

    likeBtn.addEventListener('click', function () {
      clickCount++;
      likeBtnCount.textContent = clickCount;
    });

    tweetsli.append(tweets, likeBtn, likeBtnCount);
  }
  tweetInput.value = '';
});

해결한 부분 **표시

**tweetsliContent();**

  function tweetsliContent() {
    const tweets = document.createElement('p');
    tweets.className = 'tweet-text';
    tweets.textContent = tweetInput.value;

    const likeBtn = document.createElement('button');
    likeBtn.className = 'like-button';
    likeBtn.textContent = `👍`;

    const likeBtnCount = document.createElement('p');
    likeBtnCount.className = 'like-counter';
    likeBtnCount.textContent = '';

    let clickCount = 0;

    likeBtn.addEventListener('click', function () {
      clickCount++;
      likeBtnCount.textContent = clickCount;
    });

    **tweetsli.append(tweets, likeBtn, likeBtnCount);**
  }

'undefined'가 떴던 이유는 이전 코드의 ' tweetsli.append(tweetsliContent());' 때문이었다.
우선적으로
1. append는 함수를 인자로 받지 않는다.
append() 메서드는 문자열이나 노드객체만 인자로 받을 수 있다. 직접적으로 함수를 인자로 받을 수는 없다.
(참고자료 자바스크립트 공식문서: https://developer.mozilla.org/en-US/docs/Web/API/Element/append)
2. 위 코드에서는 'tweetsliContent()'를 직접적으로 인자로 받았으므로 해당 함수의 반환값(위 함수에서는 return문이 없기에 반환값은 없지만)'undefined'가 떴다. 하지만 자바스크립트는 유연한 언어이기에 오류가 뜨는 것이 아닌 'undefined' 문자열이 나온 것이다.
3. 사실상 'tweetsli.append(tweets, likeBtn, likeBtnCount);'가 있기에 불필요한 코드이다. 함수 안에 tweetsli에 append 해준다는 내용이 적혀있으므로 필요 없는 문구였다.

따라서 tweetsliContent함수 안에 tweetsli.append(tweets, likeBtn, likeBtnCount); 써서 tweetsli에 append 하였고 (DOM노드를 참고한 변수 또한 append에 사용할 수 있다. )
tweetsliContent()으로 함수를 호출해주었다.

회고: 코드를 어떤식으로 짜야 효율적인지 계속 고민했다. 그래서 나온 방법이 글의 내용, 좋아요 등 모든 내용을 내포할 li를 만들어 여러 요소를 한 바구니에 싸놓듯이 모아놓는 것.
그리고 undefined 오류를 해결하면서 append가 인자로 노드, 문자열, 노드를 참고한 변수만을 인자로 받을 수 있다는 것을 알았고 내가 불필요한 코드를 썼다는 것도 알 수 있었다.

전에는 코드 자체를 어떤 방법으로 짜야할지 감이 안왔었는데 연습하다보니 점점 틀은 대충 잡히는 느낌이 든다. 아직 문법 오류투성이에 공부해야할 것 산더미지만..

profile
hyohyo

0개의 댓글