코드 :
var errors = [];
에러 발생 변수를 문자열로 선언한다.else if(fname.match(/[^a-zA-z]/)){}
: 이름에 문자가 아니면 에러 발생.errors.push("");
: 배열이므로 .push로 에러 추가errors.join("<br>");
: 에러 요소들마다 줄 바꿈 추가.
<style> /* Contact Form */
.container{
display : grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap : 0.5rem;
}
.col-span-2{
grid-column-start: span 2;
}
label{
display : block;
font-weight: 600;
margin-bottom: 0.25rem;
}
input{
width : 100%; padding : 0.5rem; box-sizing: border-box;
}
button{
margin-top: 1rem;
padding : 0.5rem 0.75rem;
}
.warning{
color : #f00;
}
.hidden{
display: none;
}
</style>
<h1>Contact Form</h1>
<form action="" id="form">
<div class="container">
<div class="form-group">
<label for="fname">First name</label>
<input type="text" id="fname" name="fname" placeholder="John">
</div>
<div class="form-group">
<label for="lname" >Last name</label>
<input type="text" id="lname" name="lname" placeholder="Doe">
</div>
<div class="form-group col-span-2">
<label for="email">E-mail</label>
<input type="text" name="email" id="email" placeholder="JohnDoe@example.com">
</div>
</div>
<button type="submit">Submit</button>
<p id="errors" class="warning"></p>
</form>
<p id="done" class="hidden">
Thank you and we'll contact with you soon
</p>
<script>
var form = document.getElementById("form");
form.addEventListener("submit", function(e){
try{
e.preventDefault();
var fname = form.elements["fname"].value;
var lname = form.elements["lname"].value;
var email = form.elements["email"].value;
// 에러를 저장할 변수
var errors = [];
// 이름 검사
if(!fname.trim()){
errors.push("이름을 입력하세요")
}else if(fname.match(/[^a-zA-Z]/)) { // /[^o-o]/ ^ : 부정, ~아니라면
errors.push("올바른 이름을 입력하세요.");
}
// 성 검사
if(!lname.trim()){
errors.push("성을 입력하세요")
}
// 이메일 검사
if(!email.trim()){
errors.push("이메일을 입력하세요")
}
// 에러가 존재할 경우
if(errors.length){
throw errors;
}
// 통과된 경우 폼을 숨기고 떙큐메시지를 보여준다
form.classList.add("hidden");
done.classList.remove("hidden");
}catch(error){
document.getElementById("errors").innerHTML = errors.join("<br>");
}
})
</script>
localStorage
브라우저가 제공하는 저장 공간
1 localStorage의 메서드
1) localStorage.setItem(key, value)
스토리지에 데이터를 저장한다.
2) localStorage.getItem(key)
스토리지에서 데이터를 가져온다.
3) localStroage.removeItem(key)
스토리지에서 데이터를 삭제한다.
"change"
이벤트 : 체크박스의 상태가 바뀌는 것<style>
.dark-mode{
background-color: #333;
color : #fff;
}
</style>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Fuga odio temporibus exercitationem dicta molestiae eos numquam eveniet
voluptate sequi illo, ipsum recusandae mollitia, corrupti eum ab fugiat rem nihil
odit.
</p>
<input type="checkbox" id="checkbox" name="">
<label for="checkbox">
Dark Mode
</label>
<script>
var checkbox = document.getElementById("checkbox");
// 페이지가 로드되었을 때 테마 적용
var isDarkMode = localStorage.getItem("darkTheme");
if(isDarkMode){
document.body.classList.add("dark-mode");
checkbox.checked = true;
}
// change 이벤트 : 체크박스의 상태가 바뀌는 것
checkbox.addEventListener("change", function(){
var checked = this.checked;
console.log(checked);
if(checked){
document.body.classList.add("dark-mode");
// 로컬스토리지 동기화
localStorage.setItem("darkTheme", true);
}else {
document.body.classList.remove("dark-mode");
// 로컬스토리지 동기화
localStorage.removeItem("darkTheme")
}
})
</script>
코드 :
닫기 버튼을 눌렀을 때는 새로고침했을 때 다시 창이 뜨지만 그만보기 눌렀을 때는 localStorage에 값 들어가서 새로고침해도 다시 안뜸. (뜨게 하려면 application에서 삭제)
<style>
#promotion{
background-color : #333;
color : #fff;
padding : 1rem;
}
#block-btn, #close-btn{
padding : 0.5rem 0.75rem;
}
</style>
<div id="promotion">
<h1>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Itaque iste,
rerum modi tempore recusandae ex facilis? Odit suscipit obcaecati vel itaque
culpa atque, at architecto. Ipsum voluptate voluptatum illo explicabo.
</h1>
<button id="close-btn">닫기</button>
<button id="block-btn">그만보기</button>
</div>
<script>
var closeBtn = document.getElementById("close-btn");
var blockBtn = document.getElementById("block-btn");
var promotion = document.getElementById("promotion");
// 닫기 버튼을 클릭했을 때
closeBtn.addEventListener("click", function(){
promotion.remove();
})
// 로드 이벤트
if(localStorage.getItem("blockedAt")){
promotion.remove();
}
// 블락버튼을 클릭했을 때
blockBtn.addEventListener("click",function(){
promotion.remove();
localStorage.setItem("blockedAt", new Date());
})
</script>
dragover
이벤트 : 드래그 중일 때drop
이벤트 : 드랍<style>
#drop-zone{
border : 4px dashed #ddd;
padding : 4rem; text-align: center;
}
.hidden{
display : none;
}
</style>
<div id="drop-zone">
<p><i>여기</i>에 파일을 드롭하세요.</p>
</div>
<p id="done" class="hidden">제출되었습니다.</p>
<script>
var dropZone = document.getElementById("drop-zone");
var done = document.getElementById("done");
// dragover : 드래그 중
dropZone.addEventListener("dragover", dragOverHandler);
// drop : 드랍
dropZone.addEventListener("drop", dropHandler);
function dragOverHandler(e){
// 브라우저가 파일을 여는 것을 방지
e.preventDefault();
console.log("드래그 중");
}
function dropHandler(e){
// 브라우저가 파일을 여는 것을 방지
e.preventDefault();
console.log("드랍");
// 유저가 업로드한 파일
var files = Array.from(e.dataTransfer.files);
console.log("제출된 파일 : \n", files);
// 제출 메시지를 보여준다.
dropZone.classList.add("hidden");
done.classList.remove("hidden");
}
</script>
<style>
input{
padding : 0.5rem;
width : 50%;
box-sizing: border-box;
}
ul{
list-style: none;
padding : 0 0.5rem;
margin : 1rem 0 0;
}
.item{
margin-bottom: 1rem;
display : flex;
justify-content: space-between;
align-items: center;
width : 50%;
}
.delete-btn{
cursor: pointer;
}
.hidden{
display : none;
}
</style>
<input type="search" placeholder="Search Google" disabled>
<ul>
<li class="item">
I believe I can font-style
<span class="delete-btn" onclick="deleteItem(0)">×</span>
</li>
<li class="item">
I believe I can touch the sky
<span class="delete-btn" onclick="deleteItem(1)">×</span>
</li>
<li class="item">
I think about it every night and day
<span class="delete-btn" onclick="deleteItem(2)">×</span>
</li>
<li class="item">
Spread my wings and fly away
<span class="delete-btn" onclick="deleteItem(3)">×</span>
</li>
</ul>
<script>
var items = document.getElementsByClassName("item");
console.log(items);
function deleteItem(index){
items[index].classList.add("hidden");
}
</script>
<style> /* 부드럽게 등장하는 텍스트*/
.el{
opacity : 0;
transition: opacity 3s;
}
.active{
opacity : 1;
}
</style>
<h1>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Necessitatibus expedita nihil minus nemo aperiam,
soluta distinctio facilis inventore fugit vitae! Inventore quod sit vero odio earum
exercitationem, possimus saepe ex!
</h1>
<h1>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Necessitatibus expedita nihil minus nemo aperiam,
soluta distinctio facilis inventore fugit vitae! Inventore quod sit vero odio earum
exercitationem, possimus saepe ex!
</h1>
<h1>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Necessitatibus expedita nihil minus nemo aperiam,
soluta distinctio facilis inventore fugit vitae! Inventore quod sit vero odio earum
exercitationem, possimus saepe ex!
</h1>
<h1 class = "el">
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Necessitatibus expedita nihil minus nemo aperiam,
soluta distinctio facilis inventore fugit vitae! Inventore quod sit vero odio earum
exercitationem, possimus saepe ex!
</h1>
<h1 class = "el">
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Necessitatibus expedita nihil minus nemo aperiam,
soluta distinctio facilis inventore fugit vitae! Inventore quod sit vero odio earum
exercitationem, possimus saepe ex!
</h1>
<h1 class = "el">
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Necessitatibus expedita nihil minus nemo aperiam,
soluta distinctio facilis inventore fugit vitae! Inventore quod sit vero odio earum
exercitationem, possimus saepe ex!
</h1>
<script>
var els = document.getElementsByClassName("el");
document.addEventListener("scroll", function(){
// 뷰포트의 높이
var vh = window.innerHeight;
for ( var i = 0; i<els.length; i++){
// 뷰포트 탑과 엘리먼트 탑사이의 거리
var y = els[i].getBoundingClientRect().y;
console.log(`${i}엘리먼트의 y값 : `, y);
if( y < vh * 0.9){ // 뷰포트에 충분히 진입했을 때}
els[i].classList.add("active");
}
}
})
</script>