
실습 : https://stackblitz.com/edit/stackblitz-starters-ovnvnm?file=script.js
input창에 글을 입력하면 밑에 트윗 형식으로 글의 리스트가 나오고 좋아요 버튼과 좋아요 개수를 표기할 수 있는 기능이 있는 웹페이지를페이지를 만든다.

전체 코드
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) 클릭 시 이벤트: ul에 들어갈 li 처리
const tweetsli = document.createElement('li');
tweetsli.className = 'tweet';
tweetsli.append(tweetsliContent());
tweetsUl.append(tweetsli);
제출버튼(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 = '';
제출버튼(postTweet) 클릭 시 이벤트: likeBtn눌렀을 때 처리
let clickCount = 0;
likeBtn.addEventListener('click', function () {
clickCount++;
likeBtnCount.textContent = clickCount;
});
tweetsli.append(tweets, likeBtn, likeBtnCount);
}
tweetInput.value = '';
});
'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가 인자로 노드, 문자열, 노드를 참고한 변수만을 인자로 받을 수 있다는 것을 알았고 내가 불필요한 코드를 썼다는 것도 알 수 있었다.
전에는 코드 자체를 어떤 방법으로 짜야할지 감이 안왔었는데 연습하다보니 점점 틀은 대충 잡히는 느낌이 든다. 아직 문법 오류투성이에 공부해야할 것 산더미지만..