<button type="submit" disabled>로그인</button>
formEl.addEventListener('input', (e) => {
e.preventDefault();
if (e.target.tagName !== 'INPUT') {
return;
}
if (userId.value && userPw.value.length >= 6) {
// < 1.조건에 충족하면 버튼을 활성화 >
btnEl.disabled = false; // (방법1)
// btnEl.removeAttribute('disabled'); // (방법2)
} else {
btnEl.disabled = true; // < 2. 조건에 충족하지 못하면, 버튼을 비활성화시킴. >
}
});
구상1
처음엔 로그인 버튼이 비활성화 상태로 시작.
id값이 1개 이상, 비밀번호 값이 6개 이상이 되면 버튼이 활성화 되게끔 함.👉 button태그의 disabled 속성 활용.
<form>
<div class="field">
<label>
<span>전화번호, 사용자 이름 또는 이메일</span>
<input type="text" id="userId" autocomplete="off" /> // 구상3-2.
</label>
</div>
<div class="field">
<label>
<span>비밀번호</span>
<input type="password" id="userPassword" /> // 구상.1-1
</label>
</div>
<button type="submit" disabled>로그인</button> // 구상.1-2
</form>
formEl.addEventListener('submit', (e) => {
e.preventDefault(); // 구상4
if (btnEl.disabled) { // 구상.2-1. 버튼이 유효성이 맞지 않아 비활성화 상태면 submit되지 않음.
return;
}
location.href = 'main.html'; // 구상.2-2. 버튼이 유효성이 맞아 활성화되면 main창으로 이동시킴.
});
// <id 기억하기>
window.addEventListener('pageshow', () => { // 구상3-1. 로그인시 main창으로 이동하기
if (userId.value || userPw.value) {
fieldEl.classList.add('hasValue');
}
});
구상1
비밀번호 입력후 엔터를 쳐도, 로그인 버튼을 클릭해도 form이 submit되도록 하려함.
👉form 태그 안의 input태그를 엔터하거나, button태그를 click하여 form을 submit하도록 함.
: 폼을 전송하는 방법은 크게 두 가지가 있다. (참고자료: https://ko.javascript.info/forms-submit )
1) <button type="submit">
Click 하기
2) input요소에서 Enter 키 누르기
구상2
로그인창을 submit하면 메인창으로 페이지 이동하기
👉 location.href= " " 이용
location.href = "main.html";
location.replace("main.html");
구상3 -1
폼요소의 아이디 값을 기억하고 있기.
: 로그인 후 main페이지에서 뒤로가기하여 로그인 창으로 이동시, 기존에 입력한 아이디값 저장해놓기👉 pageshow 이벤트 활용
: 네비게이션으로 인해 페이지가 이동해서 이벤트가 걸린 페이지가 보여졌을때 이벤트 콜백함수가 실행됨
(반대개념 pageshide)
구상3 -2
폼 요소의 아이디 값 지우기
: 로그인 후 main페이지에서 다시 로그인 창으로 이동시, 기존에 입력한 아이디값 저장하지 않으려면?👉 autocomplete 활용
: 브라우저가 이 필드에 값을 자동으로 넣는 것을 금지함. 보안상 문제로 자동완성을 사용하지 않아야 할 경우 사용.
<form>
<input type="text" id="userId" autocomplete="off" />
</form>
구상4
form이 submit 될 때 하는 기본 동작 막기
👉 e.preventDefault() 사용
form을 submit하면 action속성에 지정된 url로 post요청을 하며, 페이지가 그 url로 넘어간다. 때문에 현 페이지에서 실행중인 js들이 모두 무시된다.
따라서 위 동작을 막기 위해 e.preventDefault()를 써서 이 form요소의 기본 기능을 막아야 한다.
<ul id="comments">
<li>
<button type="button" class="heartBtn emptyBtn">
<svg>
<path d="M16.7..."></path>
</svg>
</button><button type="button" class="delBtn">
<button type="button" class="delBtn">삭제</button>
</li>
<li></li>...<li></li>
</ul>
// 1.이벤트 위임 사용
const commentsEl = document.querySelector('#comments');
commentsEl.addEventListener('click', (e) => {
// console.log(e.target.tagName); // BUTTON svg path
// 2.하트버튼 이벤트
const heartBtnEl = e.target.closest('.heartBtn');
if (heartBtnEl) {
if (heartBtnEl.classList.contains('emptyBtn')) {
heartBtnEl.classList.toggle('emptyBtn');
heartBtnEl.classList.toggle('redBtn');
heartBtnEl.innerHTML = `<svg><path d="M34..."></path></svg>
`;
return;
}
if (heartBtnEl.classList.contains('redBtn')) {
heartBtnEl.classList.toggle('emptyBtn');
heartBtnEl.classList.toggle('redBtn');
heartBtnEl.innerHTML = `<svg>
<path d="M16..."></path>
</svg>`;
return;
}
}
// 3. 삭제버튼 이벤트
const delBtnEl = e.target.classList.contains('delBtn');
if (delBtnEl) {
const delLiEl = e.target.closest('li');
delLiEl.remove();
}
});
ul안에 많은 li요소가 있는데, 그 li요소 안에는 하트버튼과 삭제 버튼이 있음.
하트 버튼은 click시 색이 빨간색으로 변하는 이벤트, 삭제 버튼은 click시 li요소 자체가 삭제되는 이벤트를 걸려고 함.
✅ 이벤트 위임 사용.
모든 li의 하트버튼, 삭제버튼 각각에 이벤트를 걸고 콜백 함수를 걸어주기 보단, 이 li요소를 모두 감싸고 있는 ul태그에 한번에 걸어주는게 더 효율적임!
상위 요소인 ul요소에 이벤트를 한번에 걸어주고, 이벤트 위임으로 이벤트를 캐치하게끔 하였음.
하트 버튼이 눌리게끔 하기 위해 하트 svg요소를 버튼 안에 넣었음.
때문에 버튼을 누르면 e.target.tagName이 "BUTTON", "svg", "path"이 나오게 됨.
따라서 이 모든 태그를 감싸고 있는 button태그에 접근하여 클래스명을 따져서 현재 svg가 빈하트인지? 빨간 하트인지? 따져야 함.
✅ 1. e.target.parentelement...로 버튼 요소까지 접근한다면?
"BUTTON", "svg", "path" 각각의 경로가 다르기 때문에 너무 복잡해짐.
✅ 2. e.target.closest("선택자") 사용
때문에 closest을 사용하여 특정 선택자(.heartBtn)와 일치하는 요소를 찾을 때 까지 위로 순회하게 함.
내용작성!