간단한 도서관 앱
소개
HTML, CSS 및 JavaScript로 만든 TheOdinProject 커리큘럼의 프로젝트입니다.
Live Demo | Github Repo
목적
다음과 같이 예상되는 작은 도서관 앱을 만듭니다.
let myLibrary = [];
function Book() {
// the constructor
}
function addBookToLibrary() {
// do stuff
}
HTML 및 CSS 정보
Spectre-CSS 프레임워크를 사용하여 테이블과 양식을 만든 템플릿을 제공하겠습니다. 정말 간단하고 이 라이브러리 앱을 만드는 용도로만 사용되는 겸손한 레이아웃입니다.
이번 챌린지에서 저는 JavaScript에 정말 관심이 많았습니다.
실습
먼저 생성자 함수를 완성하기 시작했습니다.
도서 생성자
function Book(title, author, pages, status) {
const id = Math.floor(Math.random() * 10000);
this.title = title;
this.author = author;
this.pages = pages;
this.status = status;
this.id = id;
}
여기서 전체 아이디어는 각 책 항목에 대해 고유한 ID를 만드는 것입니다.
왜요? 나중에 배열에서 고유한 항목을 삭제하는 기능을 추가하고 싶기 때문입니다. 배열에서 인덱스를 찾으려면 이 파일
id
이 필요합니다.이제 Book Constructor를 사용하여 새 책을 만들 수 있습니다.
DOM
를 사용하여 .addEventListener
를 조작하여 입력 항목을 캡처하고 새 책을 만들 수 있습니다.이벤트 리스너: 새 책 추가
document.querySelector('form').addEventListener('submit', e => {
e.preventDefault();
//Create a new book
const title = document.querySelector('#bookTitle').value;
const author = document.querySelector('#bookAuthor').value;
const pages = document.querySelector('#bookPages').value;
const status = document.querySelector('input[name="readStatus"]:checked').value;
const book = new Book(title, author, pages, status);
//Add new book to library
addBookToLibrary(book);
}
이제 이 책을
myLibrary
배열에 추가하고 배열을 반복하여 렌더링해야 합니다.어레이 푸시: 라이브러리에 책 추가
function addBookToLibrary(book) {
myLibrary.push(book);
//What to do after I push the new book to the library
displayBooks();
clearFields();
}
함수
displayBooks
는 각 책에 대한 정보로 테이블의 행을 렌더링합니다. 그리고 함수clearFields()
는 화면에서 내 입력 값을 지울 것입니다.렌더링 테이블 행
function displayBooks() {
const tBody = document.querySelector('#bookRow');
tbody.querySelectorAll('tr').forEach(el => el.remove());
myLibrary.forEach(book => {
createRow(book)
});
}
function clearFields() {
document.querySelector('#bookTitle').value = '';
document.querySelector('#bookAuthor').value = '';
document.querySelector('#bookPages').value = '';
}
이 코드 줄에 대해 이야기해야 합니다.
tbody.querySelectorAll('tr').forEach(el => el.remove());
이 코드를 작성하면서 첫 번째, 두 번째, 세 번째에 어려움을 겪었습니다.
테이블을 다시 렌더링할 때마다 테이블이 복제되었습니다.
이것이 제가 찾은 기능적 솔루션입니다.
tr
에서 <tbody>
를 모두 제거합니다.이것이 최선의 솔루션인지는 모르겠지만 저와 이 프로젝트에 효과적이었습니다.
테이블 행 만들기
function createRow(book) {
const tbody = document.querySelector('#bookRow');
const row = document.createElement('tr');
if (book.status === 'true') {
row.innerHTML = `
<td>${book.title}</td>
<td>${book.author}</td>
<td>${book.pages}</td>
<td>Read</td>
<td id="delete">Delete</td>
`
} else {
row.innerHTML = `
<td>${book.title}</td>
<td>${book.author}</td>
<td>${book.pages}</td>
<td>Not Read</td>
<td id="delete">Delete</td>
`
}
row.classList.add(`${book.id}`)
tbody.appendChild(row);
}
이
if-else
조건은 설명적입니다.각 책의 현재 상태를 확인하고
boolean expression
를 평가합니다. 입력이 문자열을 반환하기 때문에 문자열과 비교됩니다.또한 Book Constructor에서 생성된 고유 ID를 사용하여 각각에 대한 클래스 이름
<tr>
을 추가합니다.이벤트 리스너: 책 삭제 및 상태 변경
document.querySelector('table').addEventListener('click', e => {
if (e.target.textContent === 'Delete') {
const id = e.target.parentElement.className;
deleteBook(id);
}
if (e.target.textContent === 'Read' || e.target.textContent === 'Not Read') {
const id = e.target.parentElement.className;
changeStatus(id);
}
})
여기에서 실제로 내
table
와 상호 작용할 수 있습니다. string values
로 렌더링하고 있으므로 실행하려는 기능을 트리거하기 위해 정확히 .textContent
를 찾고 있습니다.function deleteBook(id) {
myLibrary.forEach((book, i) => {
if (book.id == id) {
myLibrary.splice(i, 1);
}
})
displayBooks();
}
function changeStatus(id) {
myLibrary.forEach((book, i) => {
if (book.id == id) {
if (book.status === 'true') {
book.status = 'false'
} else {
book.status = 'true'
}
}
})
displayBooks();
}
각 변경 후에는
displayBooks()
를 다시 호출합니다. 내 테이블을 다시 렌더링하고(내 tbody
내부의 모든 항목 제거) 새 배열m̀yLibrary
또는 업데이트된 배열length
을 사용하여 새 배열book.status
을 렌더링합니다.그게 다야.
나는 당신이 이 튜토리얼과 내가 이 도전을 어떻게 해결했는지 즐겼기를 바랍니다!
내에서 나를 따르라!
Reference
이 문제에 관하여(간단한 도서관 앱), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/mpfdev/simple-library-app-14bm텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)