자바스크립트 주요기능 구현하기(1), (2): To-do, MouseAnimation, Scroll-top, Modal
github소스코드
reset.css
활용함text-indent
: 들여쓰기(양수), 내어쓰기(음수), 기본값 0header input {
float: left;
width: 100%;
height: 50px;
background-color: rgba(255,255,255,.3);
border: 0;
outline: none;
color: #fff;
font-size: 15px;
text-indent: 18px;
}
header input::-webkit-input-placeholder {
color: #fff;
}
// add 버튼 객체 가져오기
var addBtn = document.getElementById('add');
// add 버튼 클릭 시 이벤트
addBtn.addEventListener('click', function() {
var value = document.getElementById('txt').value;
// if문을 사용해서 value값이 있을 때를 구분해줌
if(value) {
addListTodo(value);
document.getElementById('txt').value = '';
}
});
function addListTodo(text) {
// 1. li 태그 넣을 ul 가져오기
var list = document.getElementById('todo');
// 2. li 태그 만들고 text 삽입
var item = document.createElement('li');
item.textContent = text;
// 3. 버튼 감싸는 영역 만들기
var buttons = document.createElement('div');
buttons.classList.add('buttons');
// 4. 삭제, 완료 버튼 생성 및 이벤트리스너 붙이기
var removeBtn = document.createElement('button');
removeBtn.classList.add('remove');
removeBtn.addEventListener('click', removeList);
var completeBtn = document.createElement('button');
completeBtn.classList.add('complete');
completeBtn.addEventListener('click', completeList);
// 5. 각 태그들 배치(조립)조립하기
buttons.appendChild(removeBtn);
buttons.appendChild(completeBtn);
item.appendChild(buttons);
// 6. 리스트의 최 상단에 아이템 삽입
// list.appendChild(item); // 가장 마지막에 삽입됨
// childNodes[]로 리스트의 첫번째 자식 선택-> 그 앞에 삽입
list.insertBefore(item, list.childNodes[0]);
};
function removeList() {
// this = 이벤트 발생하는 객체인 removeBtn
// parentNode 활용해 부모의 부모인 li 태그 선택
var item = this.parentNode.parentNode;
var parent = item.parentNode;
parent.removeChild(item);
}
function completeList() {
var item = this.parentNode.parentNode;
var parent = item.parentNode;
var id = parent.id;
// 기존 리스트에서 삭제
parent.removeChild(item);
// 삼항연산자로 id값에 따라 target 영역 바꾸기
var target = (id === 'todo')
? document.getElementById('completed')
: document.getElementById('todo');
// 최신순 업데이트
target.insertBefore(item, target.childNodes[0]);
}
.page-back {
position: absolute;
width: 120%;
height: 120%;
background: url(bg.jpg) no-repeat;
background-size: cover;
background-position: center;
left: -10%;
top: -10%;
}
window.innerWidth
: 브라우저 내부 너비window.innerHeight
: 브라우저 내부 높이var pageContainer = document.querySelector('.page-container');
var pageBack = document.querySelector('.page-back');
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
mousemove
: 이벤트 종류 중 하나로 마우스 움직일 때마다 이벤트 일어남mousemove
를 이벤트객체 e로 받아서 마우스 현재 좌표를 나타내는 pageX, pageY 프로퍼티 사용 가능var moveX = ((windowWidth/2) - e.pageX) * 0.1;
var moveY = ((windowHeight/2) - e.pageY) * 0.1;
pageContainer.addEventListener('mousemove', function(e){
var moveX = ((windowWidth/2) - e.pageX) * 0.1;
var moveY = ((windowHeight/2) - e.pageY) * 0.1;
pageBack.style.transform = `translate(${moveX}px, ${moveY}px)`;
});
transition: all
: 클래스 변화로 인한 효과도 부드럽게 만들어 줌nav {
position: fixed;
width: 100%;
background-color: #000000;
border-bottom: solid 1px rgba(0, 0, 0, .1);
padding: 22px 100px;
transition: all 0.5s;
}
window.addEventListener('scroll')
window.onScroll = function () { ... }
document.addEventListener('scroll')
window.addEventListener('scroll', function() {
var top = window.scrollY // explorer 제외 모든 브라우저
|| window.pageYOffset // explorer 9 이상 가능
|| document.documentElement.scrollTop // explorer 8 이하 가능, chrome 불가
|| document.body.scrollTop; // 크롬, 사파리, 오페라, 엣지 사용 가능
// 스크롤 위치 내려가면 nav class 추가해줌
(top > 50)
? fixedNav.classList.add('active')
: fixedNav.classList.remove('active');
});
var oldVal = 0; //기준점
window.addEventListener('scroll', function () {
var newVal = window.scrollY
|| window.pageYOffset
|| document.documentElement.scrollTop
|| document.body.scrollTop;
if(oldVal - newVal < 0) {
fixedNav.classList.add('active');
}
if(oldVal - newVal > 0) {
fixedNav.classList.remove('active');
}
oldVal = newVal;
});
wheelDelta
값이 있을수도 있고 없을수도 있어서 삼항연산자 사용window.addEventListener('wheel', mouseWheelEvt);
window.addEventListener('DOMMouseScroll', mouseWheelEvt);
function mouseWheelEvt(e) {
var index = e.wheelDelta ? e.wheelDelta : -e.detail;
(index < 0)
? fixedNav.classList.add('active')
: fixedNav.classList.remove('active');
};
navigator.userAgent
: 접속한 브라우저 종류를 문자열로 리턴navigator.userAgent.indexOf('Firefox')
: 글자가 존재하면 위치값, 없으면 -1 리턴var isFirefox = (navigator.userAgent.indexOf('Firefox')===-1) ? false : true;
var wheelEvt = isFirefox ? 'DOMMouseScroll': 'wheel';
window.addEventListener(wheelEvt, mouseWheelEvt);
function mouseWheelEvt(e) {
var index = e.wheelDelta ? e.wheelDelta : -e.detail;
(index < 0)
? fixedNav.classList.add('active')
: fixedNav.classList.remove('active');
};
visibility
: hidden, visible 등의 속성값을 이용해 객체를 보이거나 안 보이게 할 수 있는 css 속성visibility: hidden
과 display: none
의 차이점: display는 객체 공간의 크기 인식 못해서 다른 객체가 땡겨지는데 visibility는 보이진 않지만 공간은 여전히 차지해서 레이아웃에 영향 주지 않는다..modal {
position: fixed;
visibility: hidden;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0;
z-index: 999999;
transition: all 0.5s;
}
.modal.active {
visibility: visible;
opacity: 1;
}
.modal .modal-wrap {
position: absolute;
width: 500px;
background-color: white;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
var btnModal = document.querySelector('.btn-modal');
var modal = document.querySelector('.modal');
var btnClose = document.querySelector('.modal .btn-close');
btnModal.addEventListener('click', function() {
modal.classList.add('active');
});
btnClose.addEventListener('click', function() {
modal.classList.remove('active');
});
modal.addEventListener('click', function(e) {
var target = e.target; // modal 영역 안 클릭한 태그 반환
var isLayer = target.classList.contains('modal-layer');
if(isLayer) {
modal.classList.remove('active');
}
});
오늘은 자바스크립트를 이용해 자주 구현되는 기능들을 몇 가지 연습했다. 크로스 브라우징은 전혀 생각해보지 못했는데 배울 수 있어서 좋았다. 여러 다양한 웹디자인을 만들어 보고 싶다.