```html
<body>
<header></header>
<main class="container">
<div class="login-container">
<div class="westagram-logo">westagram</div>
<input type="text" class="login id-box" placeholder="전화번호, 사용자 이름 또는 이메일">
<input type="password" class="login pw-box" placeholder="비밀번호">
<button id="login-button" disabled>로그인</button>
<div class="forgot-pw"><a href="https://www.instagram.com/accounts/password/reset/">비밀번호를 잊으셨나요?</a></div>
</div>
</main>
</body>
```

<div>
를 사용하였는데, 이후 wrap-up 세션에서 <main>
or <form>
과 같은 semantic 태그를 활용하는 것이 좋다는 피드백을 받아서 앞으로 프로젝트에서는 semantic 태그를 적극적으로 활용하는 방식으로 구현해야겠다.#login-button:hover:enabled {
cursor: pointer;
}
const loginId = document.getElementsByClassName('login')[0];
const loginPw = document.getElementsByClassName('login')[1];
const loginButton = document.getElementById('login-button');
function activateLoginButton (){
let idValueLength = loginId.value.length;
let pwValueLength = loginPw.value.length;
(loginId.value.includes('@') && pwValueLength>5) ?
(loginButton.disabled = false) :
(loginButton.disabled = true)
}
loginId.addEventListener('keyup', activateLoginButton);
loginPw.addEventListener('keyup', activateLoginButton);
loginButton.addEventListener('click', () => {
window.location.href = '../main.html';
})
use strict
을 전역에 정의함으로써 오류가 발생하기 쉬운 유연한 자바스크립트의 특징을 방지하여 초기에 오류를 찾아낼 수 있게했다."use strict";
const loginId = document.getElementsByClassName('login')[0];
const loginPw = document.getElementsByClassName('login')[1];
const loginButton = document.getElementById('login-button');
const checkValue = () => {
let pwValueLength = loginPw.value.length;
return !(loginId.value.includes('@') && pwValueLength>5);
}
const lgnBttnHandler = () => {
loginButton.disabled = checkValue();
}
const init = () => {
loginId.addEventListener('input', lgnBttnHandler);
loginPw.addEventListener('input', lgnBttnHandler);
loginId.addEventListener('keyup', lgnBttnHandler);
loginPw.addEventListener('keyup', lgnBttnHandler);
loginButton.addEventListener('click', () => {
window.location.href = '../main.html';
})
};
init();
초기에 자바스크립트로 구현하려 했을 때는 로그인버튼이 활성화되는 함수를 페이지가 로드될 때 1번 호출되어 원하는대로 동작하지 않았다.
이후에 사용자가 어느정도 작성을 완료하면 동작하게 해야겠다 라고 생각하여, 이벤트리스너 속성을 걸어줬고 이 안에는 로그인 유효성 함수가 포함되어 있다.
⇒ 유효성 검사의 결과에 따른 버튼 활성화 비활성화
메인 페이지에서도 flex display 속성을 활용하여 요소들을 원하는 위치에 배치시켰다.
flex direction
과 flex가 적용된 자식요소에 각각 flex값을 부여하는 속성을 통해 원하는 대로 쉽게 위치시킬 수 있었다.
flex의 활용법을 알게되면서 사전스터디에서 자기소개페이지를 활용했을 때보다 훨씬 더 쉽게 원하는 위치에 요소들을 배치했다. 그러나,
container와 wrapper가 늘어나면서 생기는 naming에 대한 문제
그로인해 600줄이 넘어가는 css…
등의 문제점이 남아있음.
주어진 시간 내에 완성하기 위해 기능 구현에 초점을 맞춰서 작성하다보니 CSS가 많이 길어졌다.
이후 refactoring 세션을 통해 css style속성들의 배치순서, 불필요한 속성(ex. width: 100%)을 이해하였고,
부모로부터 상속 받을 수 있는 속성을 활용하거나 스타일 속성이 비슷한 요소들은 클래스로 묶어서 속성을 부여하는 방식들을 통해 코드를 줄여나가야겠다.
vw
, vh
, em
등 단위별 차이점에 대해 찾아봤다.em
은 부모 요소의 폰트사이즈에 대해서 배수로 계산한다. 예를들어 자식요소 15em이고 부모요소의 폰트사이즈가 10px이라면 15em = 10px * 15 = 150px이다.rem
은 부모요소가 아닌 최상위 요소의 폰트사이즈에 대해서 계산한다. 즉, 최상단인 html의 폰트사이즈에 대해서 배수로 적용vw
, vh
는 보여지는 화면 기준으로 사이즈를 정하는 방식이다. 1024x980에서 100vw를 주면 vw는 1024px, vh는 980px이다.<img>
태그로 넣어줬고, 피드 하단의 아이콘들은 하나의 이미지를 사용하였다.appendChild
, createElement
, className
, innerHTML
을 이용하여 함수로 구현할 생각이었다. const cmntBox = document.getElementsByClassName('comment-box')[0];
const user = document.getElementsByClassName('userOfComment-container')[0];
const cmnt = document.getElementsByClassName('commentOfUser-container')[0];
const cmntLike = document.getElementsByClassName('comment-like-container')[0];
const cmntDelete = document.getElementsByClassName('comment-delete-container')[0];
const cmntPost = document.getElementsByClassName('comment-enter-button')[0];
const init = () => {
cmntBox.addEventListener('input', activatePostButton);
cmntBox.addEventListener('keyup', activatePostButton);
cmntPost.addEventListener('click', function () {
new Comment();
})
cmntBox.addEventListener('keypress', e => {
if (e.key == 'Enter'){
new Comment();
}
})
}
init();
str.trim()
을 알게되었다.str.trim()
은 스트링 양끝 공백을 없애준다. 따라서 공백을 작성하게 되면 “” 빈값이 도출되어 falsey가 된다. const checkValue = () => {
let cmntValue = cmntBox.value;
return (cmntValue.length > 0 && !!(cmntValue.trim()))
}
const activatePostButton = () => {
cmntPost.disabled = !checkValue();
}
appendChild
, createElement
, className
, innerHTML
등을 dom요소를 이용하여 댓글을 생성하는 함수다. class Comment {
constructor() {
this.likeState = 0;
this.create();
this.liked();
this.deleted();
}
create(){
if(checkValue()){
let cmntValue = cmntBox.value;
this.cmntValue = cmntValue;
this.myId = document.createElement('span');
this.myId.className = 'userOfComment';
this.myId.innerHTML = 'ore.zeno';
user.appendChild(this.myId);
this.newcmnt = document.createElement('span');
this.newcmnt.className = 'commentOfUser';
this.newcmnt.innerHTML = this.cmntValue;
cmnt.appendChild(this.newcmnt);
this.like = document.createElement('img');
this.like.className = 'comment-like';
this.like.src = 'image/love.png';
this.like.alt = '댓글-좋아요';
cmntLike.appendChild(this.like);
this.delete = document.createElement('img');
this.delete.className = 'comment-delete';
this.delete.src = 'image/delete.png';
this.delete.alt = '댓글-삭제';
cmntDelete.appendChild(this.delete);
cmntBox.value = '';
}
}
liked(){
this.like.addEventListener('click', ()=>{
if(this.likeState == 0){
this.like.src = 'image/liked.png';
this.likeState = 1;
}
else {
this.like.src = 'image/love.png';
this.likeState = 0;
}
})
}
deleted (){
this.delete.addEventListener('click', ()=>{
this.myId.remove();
this.newcmnt.remove();
this.like.remove();
this.delete.remove();
})
}
}
```