반응형
Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- cloud firestore id auto increment
- vue draggable 차트 안나옴
- component is already mounted please use $fetch instead.
- vue3 drag and drop
- img 태그 srcset
- d3 지도 타입스크립트
- img 태그 sizes
- 헌혈유공패 은장
- 함수형 프로그래밍
- d3 지도
- reflow
- nuxt universal rendering
- commonjs와 ecmascript modules(esm)
- pm2 업데이트 에러
- 이미지 성능 최적화
- d3 지도 확대/축소
- vue 컴포저블 함수
- pm2 버전 충돌
- Learning React
- repaint
- ToDo
- firebase id 자동
- $fetch
- git
- vue composable 함수
- vuedraggable
- 인터넷 거버넌스
- 웹 퍼포먼스 도구
- d3 지도 툴팁
- in-memory pm2 is out-of-date
Archives
- Today
- Total
빵 입니다.
dom api를 사용하여 Todo 만들기 본문
반응형
기능 정의
- Todo 입력
- Todo 수정
- Todo 삭제
- Todo Total 갯수 체크
- Todo 완료 갯수 체크
- Todo 미완료 갯수 체크
어떻게 해야하는지 감이 잡히지 않아서 dom api만 가지고 개발을 했다.
우선, 코드가 매우 비효율적이다.
재사용할 수 있는 코드가 매우 적고, ES5, ES6 섞어 쓴 부분도 많다.
자바스크립트보단 html, css 단에 더 집중을 많이 한 느낌이 든다.
HTML
Todo
완료 0건 미완료 0건 총 0건
CSS
.todo_wrap{width:300px; margin:0 auto;}
.todo_wrap h1{text-align:center;}
.input_wrap{background:red;}
.input_wrap:after{content:""; display:block; clear:both;}
.input_wrap input{box-sizing:border-box; float:left; width:231px; height:40px; outline:0 none; border:1px solid #999; text-indent:5px;}
.input_wrap input:focus{border-color:#03cf5d;}
.input_wrap button{box-sizing:border-box; float:left; width:70px; height:40px; margin-left:-1px; outline:0 none; border:1px solid #03cf5d; background:#03cf5d; color:#fff;}
.input_wrap button:hover{cursor:pointer;}
.todo_list{list-style-type:none; margin:0; padding:30px 0;}
.todo_list li{line-height:30px; font-family:'Noto Sans KR', sans-serif; font-size:13px;}
.todo_list li input{vertical-align:middle;}
.todo_list li label{vertical-align:middle; cursor:pointer;}
.todo_list li button{box-sizing:border-box; width:20px; height:20px; outline:0 none; border:0 none; background:#ffffff; line-height:20px; color:red; vertical-align:middle; cursor:pointer; transition:background-color 0.5s ease;}
.todo_list li button:hover{background:#03cf5d;}
.todo_list .complete{text-decoration:line-through;}
.todo_count{}
.todo_count>span{position:relative; display:inline-block; width:30%; font-size:12px; text-align:center;}
.todo_count>span>strong{position:relative; top:1px; display:inline-block; color:#1aaf5c;}
JAVASCRIPT
// 초기화
var todoList = document.getElementById('todoList');
var btnAdd = document.getElementById('btnAdd');
var inputText = document.getElementById('txtInput');
inputText.focus();
var totalItems = 0;
var todoCount = document.getElementById('todoCount');
// todo 추가
function addNewItem(list, string){
if( inputText.value === '' || inputText.value === ' ' || !inputText ){
alert('할 일을 입력해주세요.');
return false;
}
var todoWrap = document.createElement('li');
var todoTimestamp = new Date().getTime();
todoWrap.innerHTML = `
`;
list.appendChild(todoWrap);
var chkbox = todoWrap.children[0];
chkbox.onclick = chkClassToggle;
var todoTxt = todoWrap.children[1];
todoTxt.addEventListener("dblclick", renameItem);
var btnDelete = todoWrap.children[2];
btnDelete.addEventListener("click", deleteItem);
inputText.value = '';
inputText.focus();
updateState();
}
// todo 삭제
function deleteItem(){
var todo = this.parentNode;
todoList.removeChild(todo);
updateState();
}
// 건수 계산
function updateState(){
totalItems = todoList.querySelectorAll('li').length;
var cntItem = todoList.querySelectorAll('.complete').length;
todoCount.querySelector('#cntTotal').innerHTML = totalItems;
todoCount.querySelector('#cntComplete').innerHTML = cntItem;
todoCount.querySelector('#cntIncomplete').innerHTML = totalItems - cntItem;
}
// todo 텍스트 변경 이벤트
function changeTxt(){
var todo = this.parentNode;
var todoId = this.previousElementSibling.id;
var todoValue = this.value;
if( this.getElementsByTagName('input') ){
todo.innerHTML = `
`;
var todoTxt = todo.children[1];
todoTxt.focus();
}
var chkbox = todo.children[0];
chkbox.onclick = chkClassToggle;
var todoTxt = todo.children[1];
todoTxt.addEventListener("dblclick", renameItem);
var btnDelete = todo.children[2];
btnDelete.addEventListener("click", deleteItem);
updateState();
}
// todo 내용 변경
function renameItem(){
var todo = this.parentNode;
var todoId = this.previousElementSibling.id;
var todoValue = this.innerText;
if( this.getElementsByTagName('label') ){
todo.innerHTML = `
`;
var todoTxt = todo.children[1];
todoTxt.focus();
}
todoTxt.addEventListener("focusout", changeTxt);
updateState();
}
// 체크박스 체크 시(= todo 완료 시) 클래스 추가
function chkClassToggle(){
var todoWrap = this.parentElement;
if(this.checked){
todoWrap.className = 'complete';
}else{
todoWrap.className = '';
}
updateState();
}
// 추가 버튼 이벤트
btnAdd.onclick = function(){
var todoString = inputText.value;
addNewItem(todoList, todoString);
};
// 입력 필드 키보드 이벤트
inputText.onkeyup = function(e){
if(e.which == 13){
var todoString = inputText.value;
addNewItem(todoList, todoString);
}
};
CODEPEN 확인
https://codepen.io/bread_gee/pen/pYNGZr반응형
'프론트엔드 > TODO 만들기' 카테고리의 다른 글
| Class를 사용한 함수형 프로그래밍, Todo 만들기 (1) | 2019.03.14 |
|---|---|
| Prototype를 사용한 함수형 프로그래밍, Todo 만들기 (0) | 2019.03.11 |
| 객체를 사용한 함수형 프로그래밍, Todo 만들기 (0) | 2019.03.07 |
| 배열을 사용한 함수형 프로그래밍, Todo 만들기 (0) | 2019.02.25 |
| 라인프렌즈 클론 사이트 (0) | 2018.10.22 |