script.js
를 수정하여 agoraStatesDiscussions
배열의 데이터를 나열할 수 있게 구현합니다.script.js
를 수정하여 디스커션 추가 기능을 구현합니다.section.form__container
요소에 새로운 아고라 스테이츠 질문을 추가할 수 있는 입력 폼을 제작합니다. 형식은 자유입니다.agoraStatesDiscussions
배열에 추가한 데이터가 실제 쌓여야 합니다.색을 선택할 때 센스가 부족해서 컬러헌트 사이트를 통해 도움을 받았다.
코드를 작성 할 때 복잡해 보이지 않게 작성하려고 노력했다.
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Noto Sans KR', sans-serif;
font-family: 'Ubuntu', sans-serif;
}
.form__input--title > label {
word-spacing : 7px
}
.form__input--name > label {
word-spacing : 3px
}
자바스크립트 기능구현부분에서 최대한 내 힘으로 해보려고 했으나.. 실패로 인해 다른 분들의 성공 코드를 봤다. 하지만 그 코드를 그대로 복사 붙여넣기가 아닌 이해가 되면 그 코드를 사용하는 등, 의미없는 답안 배껴쓰기가 되지 않도록 했다.
아고라 스테이츠를 찾는 사람들은 깊은 고민을 하다가 여기까지 온 것이라는 생각을 해서 심해라고 표현했고 바닷속이지만 좀 더 어두운 분위기로 디자인하려고 생각했다.
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Noto Sans KR', sans-serif;
font-family: 'Ubuntu', sans-serif;
}
/* 브라우저 초기화 */
@import url('https://fonts.googleapis.com/css?family=Amatic+SC');
body {
display: flex;
justify-content: center;
align-items: center;
background-image: url('https://mblogthumb-phinf.pstatic.net/MjAxOTA5MDZfOTYg/MDAxNTY3NzM3Mjk2Mzc3.7LtUfaRWQKnLapgW6ygwGLoPE3IHKMAFzSIQ-Uvm1rYg.z-qRlOC9t3AmEByoYiaZM5USLi187cpUrxI06y8Jgp8g.JPEG.ygpa11819/%25EC%258B%25AC%25ED%2595%25B47.jpg?type=w800');
background-repeat:no-repeat;
background-size: cover;
}
.form__input--title > label {
word-spacing : 7px
}
.form__input--name > label {
word-spacing : 3px
}
h2 {
font-family: 'Nanum Brush Script', cursive;
color: #99bcda;
}
section.form__container {
background-color: rgba(82, 213, 245, 0.5);
border-radius: 20px;
}
.discussion__answered {
padding-top: 39px;
font-size: 20px;
margin: 5px;
color: #FFF9CA;
}
.discussion__container {
display: flex;
justify-content: space-between;
align-items: center;
width: 578px;
height: 150px;
font-size : 10px;
border-radius: 19px;
margin : 10px;
padding: 20px;
}
.discussion__avatar--image {
width: 48px;
border-radius: 50%;
display: flex;
align-items: center;
margin: 5px;
}
.discussion__content{
display: block;
}
.discussion__content >:nth-child(1){
width: 440px;
text-align: left;
margin-top: 0;
}
.discussion__content >:nth-child(2){
height:30px;
text-align: right;
}
li {
list-style-type: none;
}
section.discussion__wrapper{
display: flex;
flex:4;
width: 578px;
justify-content: center;
align-items:center;
}
ul {
padding: 0px;
}
li.discussion__container {
background-color: rgba(0, 165, 231, 0.5);
}
a:link {
color: white;
font-family: 'Dongle', sans-serif;
font-size: 22px;
}
a:visited {
color: rgb(0, 0, 0);
}
/* 폼 디자인 */
h1 {
text-align: center;
margin-top: 70px;
margin-bottom: 20px;
color: #99bcda;
font-size: 40pt;
}
h3 {
text-align: center;
color: #99bcda;
margin-bottom: 20px;
}
section {
display:flex;
justify-content: center;
align-items: center;
}
form {
display: flex;
width: 500px;
flex-wrap: wrap;
flex-direction: row;
}
.form__textbox {
display: flex;
flex-direction: column;
}
#story {
width: 500px;
border-radius: 10px;
padding: 10px;
}
.form__input--wrapper {
margin: 5px;
}
.form__input--wrapper input {
width:300px;
height: 30px;
font-size:1.2rem;
margin: 5px;
border-radius: 10px;
border: 2px solid #0078AA;
}
.form__submit {
flex:1;
margin:3px;
}
.form__submit input {
width: 448px;
height: 43px;
border-radius: 10px;
font-size: 15px;
margin-left: 25px;
margin-right: 0px;
border: 2px solid black;
}
textarea {
margin : 5px;
}
.discussion__information {
padding-top: 10px;
font-size: 14px;
color: #FFF9CA;
}
img {
width: 48px;
border-radius: 100%;
}
body {
display: flex;
justify-content: center;
align-items: center;
background-image: url('https://mblogthumb-phinf.pstatic.net/MjAxOTA5MDZfOTYg/MDAxNTY3NzM3Mjk2Mzc3.7LtUfaRWQKnLapgW6ygwGLoPE3IHKMAFzSIQ-Uvm1rYg.z-qRlOC9t3AmEByoYiaZM5USLi187cpUrxI06y8Jgp8g.JPEG.ygpa11819/%25EC%258B%25AC%25ED%2595%25B47.jpg?type=w800');
background-repeat:no-repeat;
background-size: cover;
}
section.form__container {
background-color: rgba(82, 213, 245, 0.5);
border-radius: 20px;
}
// index.html을 열어서 agoraStatesDiscussions 배열 요소를 확인하세요.
console.log(agoraStatesDiscussions);
// convertToDiscussion은 아고라 스테이츠 데이터를 DOM으로 바꿔줍니다.
const convertToDiscussion = (obj) => {
const li = document.createElement("li"); // li 요소 생성
li.className = "discussion__container"; // 클래스 이름 지정
const avatarWrapper = document.createElement('div');
avatarWrapper.className = 'discussion__avatar--wrapper';
const discussionContent = document.createElement('div');
discussionContent.className = 'discussion__content';
const discussionAnswered = document.createElement('div');
discussionAnswered.className = 'discussion__answered';
// 왜 새롭게 만들어주어야하는가?
// convertToDiscussion 이 함수의 목적은 값을 추출해서 새로운 il뭉치를 만들기 위해
// TODO: 객체 하나에 담긴 정보를 DOM에 적절히 넣어주세요.
const face = document.createElement("img") // 프로필 사진
face.src = obj.avatarUrl;
face.alt = "avatar of" + obj.author;
avatarWrapper.append(face);
const discussionTitle = document.createElement("h2");
const titleAnchor = document.createElement("a");
titleAnchor.href = obj.url;
titleAnchor.textContent = obj.title;
discussionTitle.append(titleAnchor);
discussionContent.append(discussionTitle);
const discussionInfo = document.createElement("div");
discussionInfo.textContent = `${obj.author} / ${new Date(obj.createAt).toLocaleTimeString()}` // 날짜 표현 형식이 여러개가 있는데 이걸 제일 많이 쓴다
discussionContent.append(discussionTitle, discussionInfo);
const checked = document.createElement("p");
checked.textContent = obj.answer ? "☑︎" : "☒";
discussionAnswered.append(checked);
li.append(avatarWrapper, discussionContent, discussionAnswered);
return li; // il요소를 위의 함수를 통해 가공해서 append
};
// form 은 데이터를 깔끔하게 받기 위해서 받는것
//
// agoraStatesDiscussions 배열의 모든 데이터를 화면에 렌더링하는 함수입니다.
const render = (element) => { // 여기 엘리먼트는 ul.discussions__container 이게 들어옴
for (let i = 0; i < agoraStatesDiscussions.length; i += 1) {
element.append(convertToDiscussion(agoraStatesDiscussions[i]));
}
return;
};
// ul 요소에 agoraStatesDiscussions 배열의 모든 데이터를 화면에 렌더링합니다.
const ul = document.querySelector("ul.discussions__container");
render(ul);
// 화면에 그리는 작업을 렌더링이라고 하는데 지금 이 함수는 렌더링함수 이렇게 호출하면서 끝난다.
// 디스커션 추가 구현
// 문서 내용 가져오기.
const form = document.querySelector("form.form");
const author = form.querySelector("div.form__input--name > input");
const title = form.querySelector("div.form__input--title > input");
const textbox = form.querySelector("div.form__itextbox > textarea");
// submit을 클릭하면 자료를 가져온다
form.addEventListener("submit", (event) => {
event.preventDefault(); //서브밋 이벤트로 사용시 꼭 함께 사용해주어야함
const obj = {
id: "new id",
createdAt: new Date().toISOString(),
title: title.value ,
url: "https://github.com/codestates-seb/agora-states-fe/discussions",
author: author.value,
bodyHTML: textbox.value,
avatarUrl: "https://avatars.githubusercontent.com/u/97888923?s=64&u=12b18768cdeebcf358b70051283a3ef57be6a20f&v=4"
}
})
agoraStatesDiscussions.unshift(obj);
const discussion = convertToDiscussion(obj);
ul.prepend(discussion);
// index.html을 열어서 agoraStatesDiscussions 배열 요소를 확인하세요.
console.log(agoraStatesDiscussions);
// convertToDiscussion은 아고라 스테이츠 데이터를 DOM으로 바꿔줍니다.
const convertToDiscussion = (obj) => {
const li = document.createElement("li"); // li 요소 생성
li.className = "discussion__container"; // 클래스 이름 지정
const avatarWrapper = document.createElement('div');
avatarWrapper.className = 'discussion__avatar--wrapper';
const discussionContent = document.createElement('div');
discussionContent.className = 'discussion__content';
const discussionAnswered = document.createElement('div');
discussionAnswered.className = 'discussion__answered';
// 왜 새롭게 만들어주어야하는가?
// convertToDiscussion 이 함수의 목적은 값을 추출해서 새로운 il뭉치를 만들기 위해
<필수 구현기능1> TODO: 객체 하나에 담긴 정보를 DOM에 적절히 넣어주세요.const face = document.createElement("img") // 프로필 사진
face.src = obj.avatarUrl;
face.alt = "avatar of" + obj.author;
avatarWrapper.append(face);
const discussionTitle = document.createElement("h2");
const titleAnchor = document.createElement("a");
titleAnchor.href = obj.url;
titleAnchor.textContent = obj.title;
discussionTitle.append(titleAnchor);
discussionContent.append(discussionTitle);
const discussionInfo = document.createElement("div");
discussionInfo.textContent = `${obj.author} / ${new Date(obj.createAt).toLocaleTimeString()}` // 날짜 표현 형식이 여러개가 있는데 이걸 제일 많이 쓴다
discussionContent.append(discussionTitle, discussionInfo);
const checked = document.createElement("p");
checked.textContent = obj.answer ? "☑︎" : "☒";
discussionAnswered.append(checked);
li.append(avatarWrapper, discussionContent, discussionAnswered);
return li; // il요소를 위의 함수를 통해 가공해서 append
};
원래 알고있던거라 어렵지않게 배포완료
https://yeowool1010.github.io/fe-sprint-my-agora-states/
분명히 세션에서 하라는대로 했는데 왜 안되는지 의문… 글이 새로 쌓이지 않는다.. 호다닥 수정중..
⇒ 글 적고 게시글이 쌓이고 나서 폼 입력란이 빈칸을로 돌아오게 만들어주기까지 완성
디스커션 추가 기능을 위한 from.addEventListener를 활용한 이벤트 함수를 만들때 안에서 사용할 변수와 함수호출을 함수 밖에서 해버려서 작동하지 않았던것이다!
<필수 구현기능2>
TODO: 디스커션 추가
// 디스커션 추가 구현
// **함수 밖에서 선언한것 오류! addEventListener 안으로 이동해야함**
~~const form = document.querySelector("form.form");
const author = form.querySelector("div.form__input--name > input");
const title = form.querySelector("div.form__input--title > input");
const textbox = form.querySelector("div.form__itextbox > textarea");~~
// submit을 클릭하면 자료를 가져온다
form.addEventListener("submit", (event) => {
event.preventDefault(); //서브밋 이벤트로 사용시 꼭 함께 사용해주어야함
const obj = {
id: "new id",
createdAt: new Date().toISOString(),
title: title.value ,
url: "https://github.com/codestates-seb/agora-states-fe/discussions",
author: author.value,
bodyHTML: textbox.value,
avatarUrl: "https://avatars.githubusercontent.com/u/97888923?s=64&u=12b18768cdeebcf358b70051283a3ef57be6a20f&v=4"
}
})
// **함수 밖에서 선언한것 오류! addEventListener 안으로 이동해야함**
~~agoraStatesDiscussions.unshift(obj);
const discussion = convertToDiscussion(obj);
ul.prepend(discussion);~~
form.addEventListener("submit",
(event) => {
event.preventDefault(); //서브밋 이벤트로 사용시 꼭 함께 사용해주어야함
// addEventListener 안으로 선언 위치 이동
**const author = form.querySelector("div.form__input--name > input").value;
const title = form.querySelector("div.form__input--title > input").value;
const textbox = form.querySelector("div.form__textbox > textarea").value;**
const newObj = {
id: "new id",
createdAt: new Date().toISOString(),
title: title,
url: "https://github.com/codestates-seb/agora-states-fe/discussions",
author: author,
bodyHTML: textbox,
avatarUrl: "https://avatars.githubusercontent.com/u/97888923?s=64&u=12b18768cdeebcf358b70051283a3ef57be6a20f&v=4"
}
// addEventListener 안으로 선언 위치 이동
**agoraStatesDiscussions.unshift(newObj);
const discussion = convertToDiscussion(newObj);
ul.prepend(discussion);**
// submit 후 입력란 빈칸으로 리셋하는 기능 추가
**form.querySelector("div.form__input--name > input").value = "";
form.querySelector("div.form__input--title > input").value = "";
form.querySelector("div.form__textbox > textarea").value = "";
}**
)
⇒ 변수명의 오타로 인해 잘 안들어왔던것!
const discussionInfo = document.createElement("div");
discussionInfo.textContent = `${obj.author} / ${new Date(~~**obj.createAt**~~).toLocaleTimeString()}`
// obj.createAt 오타!
discussionContent.append(discussionTitle, discussionInfo);
const discussionInfo = document.createElement("div");
discussionInfo.textContent = `${obj.author} / ${new Date(**obj.createdAt**).toLocaleTimeString()}`
자바스크립트는 도대체 언제 익숙해지는걸까?
알고있는 반복문 어쩌구 이런거랑 실제 페이지에 적용하는것은 엄청난 괴리가 있다고 생각했다.
아직 자바스크립트의 명령어들을 자주 쓰지 않고 잘 몰라서 그런듯하기도하고..
내 머리가 잘 돌아가지않고 삐걱거려서 그런 부분도 좀 큰것도 같고..
제일 걱정되는것은 이런 나의 속도로 인해 함께 프로젝트할 사람이 없다면..?
그게사실 제일 걱정이다..
ㅋㅋㅋㅋㅋㅋㅋㅋ
ㅜㅜ
2022년 7월 18일 완성
2022년 7월 22일 오류 수정함!