为什么在我 运行 函数后缺少某些元素?

Why some element are missing after I run the function?

我想做搜索引擎,但是我查了一些书,怎么也查不到。它只有 return 零本书。

//data.js
// {
//   id: string | number,
//   title: string,
//   author: string,
//   year: number,
//   isComplete: boolean,
// }

const STORAGE_KEY = "BOOKSHELF_APP";

let books = [];
let booksSearched = [];

function isStorageExist() /* boolean */ {
  return false // SO does not like localStorage
  if (typeof(Storage) === undefined) {
    alert("Your browser doesn't support web storage.");
    return false;
  }
  return true;
}

function saveData() {
  const parsed /* string */ = JSON.stringify(books);
  localStorage.setItem(STORAGE_KEY, parsed);
  document.dispatchEvent(new Event("ondatasaved"));
}

function loadDataFromStorage() {
  const serializedData /* string */ = localStorage.getItem(STORAGE_KEY);

  let data = JSON.parse(serializedData);

  if (data !== null)
    books = data;

  document.dispatchEvent(new Event("ondataloaded"));
}

function updateDataToStorage() {
  if (isStorageExist())
    saveData();
}

function composeBookObject(title, author, year, isCompleted) {
  return {
    id: +new Date(),
    title,
    author,
    year,
    isCompleted
  };
}

function findBookById(bookId) {

  for (book of books) {
    if (book.id === bookId)
      return book;
  }

  return null;
}

function searchBookByTitle(bookTitle) {

  for (book of books) {
    if (book.title === bookTitle) {
      return book;
    }
  }
  return null;
}

function findBookIndexById(bookId) {

  let index = 0
  for (book of books) {
    if (book.id === bookId)
      return index;

    index++;
  }

  return -1;
}

//dom.js
const UNFINISHED_BOOK_LIST_ID = 'unfinishedBookshelfList';
const FINISHED_BOOK_LIST_ID = 'finishedBookshelfList';
const BOOK_ITEMID = "itemId";

function makeBookList(data, author, year, isCompleted) {
  const container = document.createElement('article');
  container.classList.add('book_item');
  const textTitle = document.createElement('h3');
  textTitle.innerText = `Title: ${data}`;
  const textAuthor = document.createElement('p');
  textAuthor.innerText = `Author: ${author}`;
  const textYear = document.createElement('p');
  textYear.innerText = `Year: ${year}`;
  const textContainer = document.createElement('div');
  textContainer.append(textTitle, textAuthor, textYear);
  container.append(textContainer);
  const buttonContainer = document.createElement('div');
  buttonContainer.classList.add('action');

  if (isCompleted) {
    buttonContainer.append(
      createUndoButton(),
      createTrashButton()
    );
  } else {
    buttonContainer.append(
      createCheckButton(),
      createTrashButton()
    );
  }

  container.append(buttonContainer);
  return container;
}

function createButton(buttonTypeClass /* string */ , eventListener /* Event */ ) {
  const button = document.createElement("button");
  button.classList.add(buttonTypeClass);
  button.addEventListener("click", function(event) {
    eventListener(event);
    event.stopPropagation();
  });

  if (buttonTypeClass == 'green1') {
    button.innerText = 'Belum Selesai Dibaca';
  } else if (buttonTypeClass == 'green2') {
    button.innerText = 'Selesai Dibaca';
  } else if (buttonTypeClass == 'red') {
    button.innerText = 'Hapus Buku';
  }

  return button;
}

function createUndoButton() {
  return createButton("green1", function(event) {
    // const button = document.querySelector('.green');
    // button.innerText = 'Belum Selesai Dibaca';
    undoBookFromCompleted(event.target.closest('.book_item'));
  });
}

function createTrashButton() {
  return createButton("red", function(event) {
    removeBookFromCompleted(event.target.closest(".book_item"));
  });
}

function createCheckButton() {
  return createButton("green2", function(event) {
    addBookToCompleted(event.target.closest('.book_item'));
  });
}

function addBook() {
  const unfinishedBookList = document.getElementById(UNFINISHED_BOOK_LIST_ID);
  const finishedBookList = document.getElementById(FINISHED_BOOK_LIST_ID);
  const textTitle = document.getElementById('inputBookTitle').value;
  const textAuthor = document.getElementById('inputBookAuthor').value;
  const textYear = document.getElementById('inputBookYear').value;
  const isCompleted = document.getElementById('inputBookIsCompleted').checked;

  const book = makeBookList(textTitle, textAuthor, textYear, isCompleted);
  const bookObject = composeBookObject(textTitle, textAuthor, textYear, isCompleted);

  book[BOOK_ITEMID] = bookObject.id;
  books.push(bookObject);

  if (isCompleted) {
    finishedBookList.append(book);
  } else {
    unfinishedBookList.append(book);
  }

  updateDataToStorage();
}

function addBookToCompleted(bookElement /* HTMLELement */ ) {
  const listCompleted = document.getElementById(FINISHED_BOOK_LIST_ID);
  const bookTitle = bookElement.querySelector("h3").innerText;
  const bookAuthor = bookElement.querySelector("p:nth-of-type(1)").innerText;
  const bookYear = bookElement.querySelector("p:nth-of-type(2)").innerText;

  const newBook = makeBookList(bookTitle, bookAuthor, bookYear, true);

  const book = findBookById(bookElement[BOOK_ITEMID]);
  book.isCompleted = true;
  newBook[BOOK_ITEMID] = book.id;

  listCompleted.append(newBook);
  bookElement.remove();

  updateDataToStorage();
}

function removeBookFromCompleted(bookElement /* HTMLELement */ ) {

  const bookPosition = findBookIndexById(bookElement[BOOK_ITEMID]);
  books.splice(bookPosition, 1);

  bookElement.remove();
  updateDataToStorage();
  document.dispatchEvent(new Event("onbookremoved"));
}

function undoBookFromCompleted(bookElement /* HTMLELement */ ) {
  const listUncompleted = document.getElementById(UNFINISHED_BOOK_LIST_ID);
  const bookTitle = bookElement.querySelector("h3").innerText;
  const bookAuthor = bookElement.querySelector("p:nth-of-type(1)").innerText;
  const bookYear = bookElement.querySelector("p:nth-of-type(2)").innerText;

  const newBook = makeBookList(bookTitle, bookAuthor, bookYear, false);

  const book = findBookById(bookElement[BOOK_ITEMID]);
  book.isCompleted = false;
  newBook[BOOK_ITEMID] = book.id;

  listUncompleted.append(newBook);
  bookElement.remove();

  updateDataToStorage();
}

function searchBooks(bookTitle) {
  // const bookShelf = document.querySelectorAll('.book_shelf');
  const unfinishedBookList = document.getElementById(UNFINISHED_BOOK_LIST_ID);
  const finishedBookList = document.getElementById(FINISHED_BOOK_LIST_ID);
  const bookSearchedObject = searchBookByTitle(bookTitle);
  booksSearched.push(bookSearchedObject);
  // unfinishedBookList.childElement.remove();
  // finishedBookList.childElement.remove();
  const bookSearched = makeBookList(bookSearchedObject.title, bookSearchedObject.author, bookSearchedObject.year);

  if (bookSearched.isCompleted) {
    finishedBookList.append(bookSearched);
  } else {
    unfinishedBookList.append(bookSearched);
  }

  updateDataToStorage();
}

function refreshDataFromBooks() {
  const listUncompleted = document.getElementById(UNFINISHED_BOOK_LIST_ID);
  let listCompleted = document.getElementById(FINISHED_BOOK_LIST_ID);

  for (book of books) {
    const newBook = makeBookList(book.title, book.author, book.year, book.isCompleted);
    newBook[BOOK_ITEMID] = book.id;

    if (book.isCompleted) {
      listCompleted.append(newBook);
    } else {
      listUncompleted.append(newBook);
    }
  }
}

//script.js
document.addEventListener("DOMContentLoaded", function() {

  const submitForm /* HTMLFormElement */ = document.getElementById("inputBook");
  submitForm.addEventListener("submit", function(event) {
    event.preventDefault();
    addBook();
  });

  const searchButton = document.getElementById('searchSubmit');
  searchButton.addEventListener('click', function() {
    event.preventDefault();
    console.log('ok');
    const bookList = document.querySelectorAll('.book_list article');
    bookList.forEach(list => list.remove());
    const searchBookTitleValue = document.getElementById('searchBookTitle').value;
    searchBooks(searchBookTitleValue);
  });

  if (isStorageExist()) {
    loadDataFromStorage();
  }
});

document.addEventListener("ondatasaved", () => {
  console.log("Data has been saved.");
});

document.addEventListener("ondataloaded", () => {
  refreshDataFromBooks();
  alert('Welcome back!');
});

document.addEventListener("onbookremoved", () => {
  alert('Your book has removed from the list.');
});
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

body,
input,
button {
  font-family: 'Open Sans', sans-serif;
}

input,
button {
  font-size: 16px;
}

.head_bar {
  padding: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: cornflowerblue;
  color: white;
}

main {
  max-width: 800px;
  width: 80%;
  margin: 0 auto;
  padding: 16px;
}

.input_section {
  display: flex;
  flex-direction: column;
  padding: 16px;
  border: 1px solid black;
  border-radius: 10px;
}

.input_section>h2 {
  text-align: center;
  color: cornflowerblue;
}

.input_section>form>.input {
  margin: 8px 0;
}

.input_section>form>button {
  background-color: cornflowerblue;
  color: white;
  border: 0;
  border-radius: 5px;
  display: block;
  width: 100%;
  padding: 8px;
  cursor: pointer;
}

.input_section>form>button>span {
  font-weight: bold;
}

.input_section>form>.input>input {
  display: block;
  width: 100%;
  padding: 8px;
  border-radius: 5px;
}

.input_section>form>.input>label {
  color: cornflowerblue;
  font-weight: bold;
}

.input_section>form>.input_inline {
  margin: 12px 0;
  display: flex;
  align-items: center;
}

.input_section>form>.input_inline>label {
  color: cornflowerblue;
  font-weight: bold;
  margin-right: 10px;
}

.search_section {
  margin: 16px 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 16px;
  border: 1px solid black;
  border-radius: 10px;
}

.search_section>h2 {
  color: cornflowerblue;
}

.search_section>form {
  padding: 16px;
  width: 100%;
  display: grid;
  grid-template-columns: auto 1fr 0.5fr;
  grid-gap: 10px;
}

.search_section>form>label {
  display: flex;
  align-items: center;
}

.search_section>form>input {
  padding: 5px;
  border-radius: 5px;
}

.search_section>form>button {
  background-color: cornflowerblue;
  color: white;
  border: 0;
  border-radius: 5px;
  cursor: pointer;
}

.book_shelf {
  margin: 16px 0 0 0;
  border: 1px solid black;
  padding: 16px;
  border-radius: 10px;
}

.book_shelf>h2 {
  color: cornflowerblue;
}

.book_shelf>.book_list {
  padding: 16px;
}

.book_shelf>.book_list>.book_item {
  height: auto;
  padding: 8px 16px 16px 16px;
  border: 1px solid black;
  border-radius: 5px;
  margin: 10px 0;
  display: flex;
  justify-content: space-between;
}

.book_item>.action {
  width: auto;
  height: 30px;
  margin: auto 5px;
  border-radius: 10%;
  display: flex;
  place-content: center;
  flex-basis: 1;
  gap: 5px
}

.book_shelf>.book_list>.book_item>h3,
p {
  margin: 8px 0;
}

.book_shelf>.book_list>.book_item>.action>button {
  border: 0;
  padding: 5px;
  margin: 0 5px 0 0;
  border-radius: 5px;
  cursor: pointer;
  /* }

.green1, .green2, .red { */
  display: flex;
  align-items: center;
  /* place-content: center; */
}

.book_shelf>.book_list>.book_item>.action>.green1,
.book_shelf>.book_list>.book_item>.action>.green2 {
  background-color: darkgreen;
  color: white;
}

.book_shelf>.book_list>.book_item>.action>.red {
  background-color: darkred;
  color: white;
}
<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Bookshelf Apps</title>
  <link rel="preconnect" href="https://fonts.gstatic.com">
  <link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;700;800&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <header class="head_bar">
    <h1 class="head_bar__title">Bookshelf Apps</h1>
  </header>
  <main>
    <section class="input_section">
      <h2>Input New Book</h2>
      <form id="inputBook">
        <div class="input">
          <label for="inputBookTitle">Title</label>
          <input id="inputBookTitle" type="text" required>
        </div>
        <div class="input">
          <label for="inputBookAuthor">Author</label>
          <input id="inputBookAuthor" type="text" required>
        </div>
        <div class="input">
          <label for="inputBookYear">Year</label>
          <input id="inputBookYear" type="number" required>
        </div>
        <div class="input_inline">
          <label for="inputBookIsCompleted">Finished Reading</label>
          <input id="inputBookIsCompleted" type="checkbox">
        </div>
        <button id="bookSubmit" type="submit">Input Your Book To Bookshelf <span>Unfinished Reading</span></button>
      </form>
    </section>

    <section class="search_section">
      <h2>Search Book</h2>
      <form id="searchBook">
        <label for="searchBookTitle">Title</label>
        <input id="searchBookTitle" type="text">
        <button id="searchSubmit" type="submit">Search</button>
      </form>
    </section>

    <section class="book_shelf">
      <h2>Unfinished Reading</h2>

      <div id="unfinishedBookshelfList" class="book_list">

      </div>
    </section>

    <section class="book_shelf">
      <h2>Selesai dibaca</h2>

      <div id="finishedBookshelfList" class="book_list">

      </div>
    </section>
  </main>
  <script src="js/data.js"></script>
  <script src="js/dom.js"></script>
  <script src="js/script.js"></script>
</body>

</html>

已编辑:我需要触发 onbookremoved 事件来显示警报。但是在我点击从已完成的按钮中删除图书后,警报没有出现。

dom.js

function removeBookFromCompleted(bookElement /* HTMLELement */) {

    const bookPosition = findBookIndexById(bookElement[BOOK_ITEMID]);
    books.splice(bookPosition, 1);

    bookElement.remove();
    updateDataToStorage();
    document.dispatchEvent(new Event("onbookremoved"));
}

script.js

document.addEventListener("onbookremoved", () => {
  alert('Your book has removed from the list.');
});

您的 booklist.remove 擦除了列表而不是文章

  const bookList = document.querySelectorAll('.book_list article');

我也加了

 if (book.title.toLowerCase() === bookTitle.toLowerCase()) {

你还有其他几个问题

if (book.isCompleted) { // should be bookSearched.isCompleted
    finishedBookList.append(bookSearched);
} else {
    unfinishedBookList.append(bookSearched);
}

//data.js
// {
//   id: string | number,
//   title: string,
//   author: string,
//   year: number,
//   isComplete: boolean,
// }

const STORAGE_KEY = "BOOKSHELF_APP";

let books = [];
let booksSearched = [];

function isStorageExist() /* boolean */ {
  return false // SO does not like localStorage
  if (typeof(Storage) === undefined) {
    alert("Your browser doesn't support web storage.");
    return false;
  }
  return true;
}

function saveData() {
  const parsed /* string */ = JSON.stringify(books);
  localStorage.setItem(STORAGE_KEY, parsed);
  document.dispatchEvent(new Event("ondatasaved"));
}

function loadDataFromStorage() {
  const serializedData /* string */ = localStorage.getItem(STORAGE_KEY);

  let data = JSON.parse(serializedData);

  if (data !== null)
    books = data;

  document.dispatchEvent(new Event("ondataloaded"));
}

function updateDataToStorage() {
  if (isStorageExist())
    saveData();
}

function composeBookObject(title, author, year, isCompleted) {
  return {
    id: +new Date(),
    title,
    author,
    year,
    isCompleted
  };
}

function findBookById(bookId) {

  for (book of books) {
    if (book.id === bookId)
      return book;
  }

  return null;
}

function searchBookByTitle(bookTitle) {
  console.log(bookTitle, books)
  for (book of books) {
    if (book.title.toLowerCase() === bookTitle.toLowerCase()) {
      return book;
    }
  }
  return null;
}

function findBookIndexById(bookId) {

  let index = 0
  for (book of books) {
    if (book.id === bookId)
      return index;

    index++;
  }

  return -1;
}

//dom.js
const UNFINISHED_BOOK_LIST_ID = 'unfinishedBookshelfList';
const FINISHED_BOOK_LIST_ID = 'finishedBookshelfList';
const BOOK_ITEMID = "itemId";

function makeBookList(data, author, year, isCompleted) {
  const container = document.createElement('article');
  container.classList.add('book_item');
  const textTitle = document.createElement('h3');
  textTitle.innerText = `Title: ${data}`;
  const textAuthor = document.createElement('p');
  textAuthor.innerText = `Author: ${author}`;
  const textYear = document.createElement('p');
  textYear.innerText = `Year: ${year}`;
  const textContainer = document.createElement('div');
  textContainer.append(textTitle, textAuthor, textYear);
  container.append(textContainer);
  const buttonContainer = document.createElement('div');
  buttonContainer.classList.add('action');

  if (isCompleted) {
    buttonContainer.append(
      createUndoButton(),
      createTrashButton()
    );
  } else {
    buttonContainer.append(
      createCheckButton(),
      createTrashButton()
    );
  }

  container.append(buttonContainer);
  return container;
}

function createButton(buttonTypeClass /* string */ , eventListener /* Event */ ) {
  const button = document.createElement("button");
  button.classList.add(buttonTypeClass);
  button.addEventListener("click", function(event) {
    eventListener(event);
    event.stopPropagation();
  });

  if (buttonTypeClass == 'green1') {
    button.innerText = 'Belum Selesai Dibaca';
  } else if (buttonTypeClass == 'green2') {
    button.innerText = 'Selesai Dibaca';
  } else if (buttonTypeClass == 'red') {
    button.innerText = 'Hapus Buku';
  }

  return button;
}

function createUndoButton() {
  return createButton("green1", function(event) {
    // const button = document.querySelector('.green');
    // button.innerText = 'Belum Selesai Dibaca';
    undoBookFromCompleted(event.target.closest('.book_item'));
  });
}

function createTrashButton() {
  return createButton("red", function(event) {
    removeBookFromCompleted(event.target.closest(".book_item"));
  });
}

function createCheckButton() {
  return createButton("green2", function(event) {
    addBookToCompleted(event.target.closest('.book_item'));
  });
}

function addBook() {
  const unfinishedBookList = document.getElementById(UNFINISHED_BOOK_LIST_ID);
  const finishedBookList = document.getElementById(FINISHED_BOOK_LIST_ID);
  const textTitle = document.getElementById('inputBookTitle').value;
  const textAuthor = document.getElementById('inputBookAuthor').value;
  const textYear = document.getElementById('inputBookYear').value;
  const isCompleted = document.getElementById('inputBookIsCompleted').checked;

  const book = makeBookList(textTitle, textAuthor, textYear, isCompleted);
  const bookObject = composeBookObject(textTitle, textAuthor, textYear, isCompleted);

  book[BOOK_ITEMID] = bookObject.id;
  books.push(bookObject);

  if (isCompleted) {
    finishedBookList.append(book);
  } else {
    unfinishedBookList.append(book);
  }

  updateDataToStorage();
}

function addBookToCompleted(bookElement /* HTMLELement */ ) {
  const listCompleted = document.getElementById(FINISHED_BOOK_LIST_ID);
  const bookTitle = bookElement.querySelector("h3").innerText;
  const bookAuthor = bookElement.querySelector("p:nth-of-type(1)").innerText;
  const bookYear = bookElement.querySelector("p:nth-of-type(2)").innerText;

  const newBook = makeBookList(bookTitle, bookAuthor, bookYear, true);

  const book = findBookById(bookElement[BOOK_ITEMID]);
  book.isCompleted = true;
  newBook[BOOK_ITEMID] = book.id;

  listCompleted.append(newBook);
  bookElement.remove();

  updateDataToStorage();
}

function removeBookFromCompleted(bookElement /* HTMLELement */ ) {

  const bookPosition = findBookIndexById(bookElement[BOOK_ITEMID]);
  books.splice(bookPosition, 1);

  bookElement.remove();
  updateDataToStorage();
}

function undoBookFromCompleted(bookElement /* HTMLELement */ ) {
  const listUncompleted = document.getElementById(UNFINISHED_BOOK_LIST_ID);
  const bookTitle = bookElement.querySelector("h3").innerText;
  const bookAuthor = bookElement.querySelector("p:nth-of-type(1)").innerText;
  const bookYear = bookElement.querySelector("p:nth-of-type(2)").innerText;

  const newBook = makeBookList(bookTitle, bookAuthor, bookYear, false);

  const book = findBookById(bookElement[BOOK_ITEMID]);
  book.isCompleted = false;
  newBook[BOOK_ITEMID] = book.id;

  listUncompleted.append(newBook);
  bookElement.remove();

  updateDataToStorage();
}

function searchBooks(bookTitle) {
  // const bookShelf = document.querySelectorAll('.book_shelf');
  const unfinishedBookList = document.getElementById(UNFINISHED_BOOK_LIST_ID);
  const finishedBookList = document.getElementById(FINISHED_BOOK_LIST_ID);
  const bookSearchedObject = searchBookByTitle(bookTitle) || {
    title: "na",
    author: "na",
    year: "na"
  };
  booksSearched.push(bookSearchedObject);
  // unfinishedBookList.childElement.remove();
  // finishedBookList.childElement.remove();
  const bookSearched = makeBookList(bookSearchedObject.title, bookSearchedObject.author, bookSearchedObject.year);
  // const bookElement = document.querySelectorAll('.book_item');
  // if(bookShelf !== null) {



  if (bookSearched.isCompleted) {
    finishedBookList.append(bookSearched);
  } else {
    unfinishedBookList.append(bookSearched);
  }

  updateDataToStorage();

}

function refreshDataFromBooks() {
  const listUncompleted = document.getElementById(UNFINISHED_BOOK_LIST_ID);
  let listCompleted = document.getElementById(FINISHED_BOOK_LIST_ID);

  for (book of books) {
    const newBook = makeBookList(book.title, book.author, book.year, book.isCompleted);
    newBook[BOOK_ITEMID] = book.id;

    if (book.isCompleted) {
      listCompleted.append(newBook);
    } else {
      listUncompleted.append(newBook);
    }
  }
}

//script.js
document.addEventListener("DOMContentLoaded", function() {

  const submitForm /* HTMLFormElement */ = document.getElementById("inputBook");
  submitForm.addEventListener("submit", function(event) {
    event.preventDefault();
    addBook();
  });

  const searchButton = document.getElementById('searchSubmit');
  searchButton.addEventListener('click', function() {
    event.preventDefault();
    console.log('ok');
    const bookList = document.querySelectorAll('.book_list article'); // changed
    bookList.forEach(list => list.remove());
    const searchBookTitleValue = document.getElementById('searchBookTitle').value;
    searchBooks(searchBookTitleValue);
  });

  if (isStorageExist()) {
    loadDataFromStorage();
  }
});

document.addEventListener("ondatasaved", () => {
  console.log("Data has been saved.");
});

document.addEventListener("ondataloaded", () => {
  refreshDataFromBooks();
  alert('Welcome back!');
});
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

body,
input,
button {
  font-family: 'Open Sans', sans-serif;
}

input,
button {
  font-size: 16px;
}

.head_bar {
  padding: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: cornflowerblue;
  color: white;
}

main {
  max-width: 800px;
  width: 80%;
  margin: 0 auto;
  padding: 16px;
}

.input_section {
  display: flex;
  flex-direction: column;
  padding: 16px;
  border: 1px solid black;
  border-radius: 10px;
}

.input_section>h2 {
  text-align: center;
  color: cornflowerblue;
}

.input_section>form>.input {
  margin: 8px 0;
}

.input_section>form>button {
  background-color: cornflowerblue;
  color: white;
  border: 0;
  border-radius: 5px;
  display: block;
  width: 100%;
  padding: 8px;
  cursor: pointer;
}

.input_section>form>button>span {
  font-weight: bold;
}

.input_section>form>.input>input {
  display: block;
  width: 100%;
  padding: 8px;
  border-radius: 5px;
}

.input_section>form>.input>label {
  color: cornflowerblue;
  font-weight: bold;
}

.input_section>form>.input_inline {
  margin: 12px 0;
  display: flex;
  align-items: center;
}

.input_section>form>.input_inline>label {
  color: cornflowerblue;
  font-weight: bold;
  margin-right: 10px;
}

.search_section {
  margin: 16px 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 16px;
  border: 1px solid black;
  border-radius: 10px;
}

.search_section>h2 {
  color: cornflowerblue;
}

.search_section>form {
  padding: 16px;
  width: 100%;
  display: grid;
  grid-template-columns: auto 1fr 0.5fr;
  grid-gap: 10px;
}

.search_section>form>label {
  display: flex;
  align-items: center;
}

.search_section>form>input {
  padding: 5px;
  border-radius: 5px;
}

.search_section>form>button {
  background-color: cornflowerblue;
  color: white;
  border: 0;
  border-radius: 5px;
  cursor: pointer;
}

.book_shelf {
  margin: 16px 0 0 0;
  border: 1px solid black;
  padding: 16px;
  border-radius: 10px;
}

.book_shelf>h2 {
  color: cornflowerblue;
}

.book_shelf>.book_list {
  padding: 16px;
}

.book_shelf>.book_list>.book_item {
  height: auto;
  padding: 8px 16px 16px 16px;
  border: 1px solid black;
  border-radius: 5px;
  margin: 10px 0;
  display: flex;
  justify-content: space-between;
}

.book_item>.action {
  width: auto;
  height: 30px;
  margin: auto 5px;
  border-radius: 10%;
  display: flex;
  place-content: center;
  flex-basis: 1;
  gap: 5px
}

.book_shelf>.book_list>.book_item>h3,
p {
  margin: 8px 0;
}

.book_shelf>.book_list>.book_item>.action>button {
  border: 0;
  padding: 5px;
  margin: 0 5px 0 0;
  border-radius: 5px;
  cursor: pointer;
  /* }

.green1, .green2, .red { */
  display: flex;
  align-items: center;
  /* place-content: center; */
}

.book_shelf>.book_list>.book_item>.action>.green1,
.book_shelf>.book_list>.book_item>.action>.green2 {
  background-color: darkgreen;
  color: white;
}

.book_shelf>.book_list>.book_item>.action>.red {
  background-color: darkred;
  color: white;
}
<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Bookshelf Apps</title>
  <link rel="preconnect" href="https://fonts.gstatic.com">
  <link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;700;800&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <header class="head_bar">
    <h1 class="head_bar__title">Bookshelf Apps</h1>
  </header>
  <main>
    <section class="input_section">
      <h2>Input New Book</h2>
      <form id="inputBook">
        <div class="input">
          <label for="inputBookTitle">Title</label>
          <input id="inputBookTitle" type="text" required>
        </div>
        <div class="input">
          <label for="inputBookAuthor">Author</label>
          <input id="inputBookAuthor" type="text" required>
        </div>
        <div class="input">
          <label for="inputBookYear">Year</label>
          <input id="inputBookYear" type="number" required>
        </div>
        <div class="input_inline">
          <label for="inputBookIsCompleted">Finished Reading</label>
          <input id="inputBookIsCompleted" type="checkbox">
        </div>
        <button id="bookSubmit" type="submit">Input Your Book To Bookshelf <span>Unfinished Reading</span></button>
      </form>
    </section>

    <section class="search_section">
      <h2>Search Book</h2>
      <form id="searchBook">
        <label for="searchBookTitle">Title</label>
        <input id="searchBookTitle" type="text">
        <button id="searchSubmit" type="submit">Search</button>
      </form>
    </section>

    <section class="book_shelf">
      <h2>Unfinished Reading</h2>

      <div id="unfinishedBookshelfList" class="book_list">

      </div>
    </section>

    <section class="book_shelf">
      <h2>Selesai dibaca</h2>

      <div id="finishedBookshelfList" class="book_list">

      </div>
    </section>
  </main>
  <script src="js/data.js"></script>
  <script src="js/dom.js"></script>
  <script src="js/script.js"></script>
</body>

</html>