Главная » Работа с событиями на странице: динамически изменяемый список элементов

Работа с событиями на странице: динамически изменяемый список элементов


15.04.2021, 22:13
Вводная часть



В этом практикуме , используя события на странице, мы будем динамически изменять список элементов.


Что необходимо реализовать:

Предварительно заполнить список книг на странице, используя данные вложенного в объект dataBase массива.

1. после того, как пользователь заполнил форму и нажал кнопку "Подтвердить", новая книга появляется в уже имеющемся на странице списке книг (книга добавляется в массив books объекта dataBase)
При этом страница сайта не должна перезагружаться (отменяем стандартное поведение браузера)

2. Название книги, превышающее 21 символ, обрезать, при обрезке в конце добавить троеточие.

3. Элементы списка должны удаляться при клике на иконку корзины у каждого из них.

4. При активном чекбоксе "Любимая книга", выводим алерт "Добавлено в закладки!"

5. Книги в списке отсортировать по алфавиту.

Список книг представлен в виде маркированного списка с классом book__interactive-list:

Код

  <ul class="book__interactive-list">
  <li class="book__interactive-item">Война и мир
  <div class="delete"></div>
  </li>
  <li class="book__interactive-item">Крестоносцы
  <div class="delete"></div>
  </li>
  <li class="book__interactive-item">Ивайло
  <div class="delete"></div>
  </li>
  <li class="book__interactive-item">Чингиз-хан
  <div class="delete"></div>
  </li>
  <li class="book__interactive-item">В глуби веков
  <div class="delete"></div>
  </li>
  </ul>

Блок с классом delete отвечает за вывод иконки корзины(при наведении мыши на элемент списка) для возможности удаления любого элемента из списка.

Код формы добавления новых элементов в список:

Код

  <form class="add">
  <h2>Добавить книгу в список</h2>
  <span>Введите название книги</span>
  <input class="adding__input" type="text" placeholder="Что прочитано...?">
  <span>Сделать любимой?</span>
  <input type="checkbox">
  <span class="yes">Да!</span>
  <button>Подтвердить</button>
  </form>

Разбираем решение задач

Для начала мы используем событие DOMContentLoaded, чтобы наш скрипт начал свою работу только после того, как будет полностью загружено DOM-дерево страницы сайта:

Код

document.addEventListener('DOMContentLoaded', () => {
  /* А здесь будет весь код нашего скрипта */
});

Внутри мы помещаем объект dataBase, содержащий массив books с названиями книг, именно из этого массива мы будем брать данные для динамического построения списка на странице

Код

'use strict';

document.addEventListener('DOMContentLoaded', () => {
const dataBase = {
  books: [
  "Война и мир",
  "Крестоносцы",
  "Ивайло",
  "Чингиз-хан",
  "В глуби веков"
  ]
  };
});

Для начала получим наш список книг:

Код

const bookList = document.querySelector('.book__interactive-list');

Очищаем его, заменяя содержимое пустой строкой, используя свойство innerHTML:

Код

bookList.innerHTML = "";

Устанавливаем сортировку по алфавиту для будущего, динамически формируемого, списка книг:

Код

dataBase.books.sort();

Теперь перебираем массив books из объекта с помощью метода forEach(), при этом каждый элемент массива оборачиваем в тег li с классом promo__interactive-item.

Код

  dataBase.books.forEach((book, i) => {
  bookList.innerHTML += `
  <li class="book__interactive-item">${i + 1} ${book}
  <div class="delete"></div>
  </li>
  `;
  });

Тем самым формируем динамически список книг.

Чтобы взаимодейстовать с нужными элементами на странице, их предварительно нужно получить.

Нам для решения наших задач понадобится получить со страницы форму добавления новых книг, поле ввода новой книги и чекбокс, отвечающий за отметку, сделать её любимой или нет

Код

const addForm = document.querySelector('form.add'),
  addInput = addForm.querySelector('.adding__input'),
  checkbox = addForm.querySelector('[type="checkbox"]');

Для формы добавления новой книги добавляем обработчик события submit и отменяем стандартное поведение браузера:

Код

  addForm.addEventListener('submit', (event) => {
  event.preventDefault();
  });

Создадим новую переменную newBook, в неё мы будем сохранять данные, которые ввёл пользователь в поле формы:

Код

  addForm.addEventListener('submit', (event) => {
  event.preventDefault();

  const newBook = addInput.value;
  });

А также переменную favorite, в которой отслеживается булиновое значение (отмечен или нет флажком чекбокс)

Теперь пишем условие, что если пользователь что-то ввёл в поле добавления новой книги, то эти данные должны добавляться в массив dataBase.books

Код

  addForm.addEventListener('submit', (event) => {
  event.preventDefault();

  let newBook = addInput.value;
  const favorite = checkbox.checked;

  if (newBook) {
  dataBase.books.push(newBook);
  dataBase.books.sort();
  }
  });

Мы добавили новую книгу в объект dataBase, но нам нужно теперь вывести обновлённый список книг на страницу.

Выше мы уже написали код для реализации этого, остаётся только объединить его в функцию, чтобы его можно было использовать, не прописывая повторно:

Код

  function createBooksList() {
  bookList.innerHTML = "";
   
  dataBase.books.forEach((book, i) => {
  bookList.innerHTML += `
  <li class="book__interactive-item">${i + 1} ${book}
  <div class="delete"></div>
  </li>
  `;
  });
  }

Чтобы сделать функцию более универсальной (не привязанной к каким-то элементам страницы), перепишем её, добавив ей аргументы books и parent, после чего вызовем её, чтобы сформировать начальный список книг на странице:

Код

  function createBooksList(books,parent) {
  parent.innerHTML = "";
   
  books.forEach((book, i) => {
  parent.innerHTML += `
  <li class="book__interactive-item">${i + 1} ${book}
  <div class="delete"></div>
  </li>
  `;
  });
  }

  createBooksList(dataBase.books, bookList);

В аргумент parent мы передаём родительский элемент, а в аргумент books наши книги из вложенного в объект dataBase массива

Также вынесем в отдельную функцию сортировку массива:

Код

'use strict';

document.addEventListener('DOMContentLoaded', () => {

  const dataBase = {
  books: [
  "Война и мир",
  "Крестоносцы",
  "Ивайло",
  "Чингиз-хан",
  "В глуби веков"
  ]
  };

  const bookList = document.querySelector('.book__interactive-list'),
  addForm = document.querySelector('form.add'),
  addInput = addForm.querySelector('.adding__input'),
  checkbox = addForm.querySelector('[type="checkbox"]');

   
  const sortArr = (arr) => {
  arr.sort();
  }; /* создали функцию для сортировки какого-либо массива */

  sortArr(dataBase.books); /* вызвали функцию сортировки, передав ей как аргумент массив с книгами */

  function createBooksList(books,parent) {
  parent.innerHTML = "";

  books.forEach((book, i) => {
  parent.innerHTML += `
  <li class="book__interactive-item">${i + 1} ${book}
  <div class="delete"></div>
  </li>
  `;
  });
  } /* создали функцию добавления новых элементов в родительский элемент */

  createBooksList(dataBase.books, bookList); /* создаём список на странице на основе начальных данных массива */

  addForm.addEventListener('submit', (event) => {
  event.preventDefault();

  let newBook = addInput.value;
  const favorite = checkbox.checked;

  if (newBook) {
  dataBase.books.push(newBook);
  sortArr(dataBase.books); /* вызвали функцию сортировки, передав ей как аргумент обновлённый массив с книгами */
  }
  });

});


Теперь нам нужно также вызвать функцию createBooksList() для обработчика событий формы, так как нам нужно сформировать обновлённый список после добавления в массив новой книги.

В конце очищаем форму, удаляя из неё данные с помощью метода reset() для объекта события:

Код

  addForm.addEventListener('submit', (event) => {
  event.preventDefault();

  let newBook = addInput.value;
  const favorite = checkbox.checked;

  if (newBook) {
  dataBase.books.push(newBook);
  sortArr(dataBase.books);

  createBooksList(dataBase.books, bookList); /* создаём список на странице на основе обновлённых данных массива */
  }

  event.target.reset(); /* очищаем данные формы */
  });

Запишем проверку для новой добавляемой книги, если длина её названия больше 21 символа, обрезаем её:

Код

  if (newBook) {

  if (newBook.length > 21) {
  newBook = `${newBook.substring(0,22)}...`;
  } /* проверяем длину названия и обрезаем при необходимости */

  dataBase.books.push(newBook);
  sortArr(dataBase.books);

  createBooksList(dataBase.books, bookList); /* создаём список на странице на основе обновлённых данных массива */
  }

Для реализации удаления элементов из списка при клике на иконку корзинки, нужно добавить обработчик события для каждого блока div с классом delete:

Код

  function createBooksList(books,parent) {
  parent.innerHTML = "";

  books.forEach((book, i) => {
  parent.innerHTML += `
  <li class="book__interactive-item">${i + 1} ${book}
  <div class="delete"></div>
  </li>
  `;
  });

  document.querySelectorAll('.delete').forEach((btn, i) => {
  btn.addEventListener('click', () => {
  btn.parentElement.remove(); /* удаляем родительский элемент при клике на иконку */
  dataBase.books.splice(i, 1); /* удаляем элемент с индексом i из массива */
  createBooksList(books,parent); /* перестраиваем элементы списка чтобы обновить нумерацию */
  });
  });
  }

Добавляем сортировку списка при его создании:

Код

  function createBooksList(books,parent) {
  parent.innerHTML = "";
  sortArr(books); /* сортируем список по алфавиту */

  books.forEach((book, i) => {
  parent.innerHTML += `
  <li class="book__interactive-item">${i + 1} ${book}
  <div class="delete"></div>
  </li>
  `;
  });

  document.querySelectorAll('.delete').forEach((btn, i) => {
  btn.addEventListener('click', () => {
  btn.parentElement.remove(); /* удаляем родительский элемент при клике на иконку */
  dataBase.books.splice(i, 1); /* удаляем элемент с индексом i из массива */
  createBooksList(books,parent); /* перестраиваем элементы списка чтобы обновить нумерацию */
  });
  });
  }

Добавляем проверку условия для чекбокса (любимая книга):

Код

  addForm.addEventListener('submit', (event) => {
  event.preventDefault();

  let newBook = addInput.value;
  const favorite = checkbox.checked;

  if (newBook) {

  if (newBook.length > 21) {
  newBook = `${newBook.substring(0,22)}...`;
  }

  if (favorite) {
  alert('Добавлено в закладки!');  
  } /* если галочка у чекбокса стоит, значит true */

  dataBase.books.push(newBook);
  sortArr(dataBase.books);

  createBooksList(dataBase.books, bookList); /* создаём список на странице на основе обновлённых данных массива */
  }

  event.target.reset(); /* очищаем данные формы */
  });

Полный код получившегося скрипта:

Код

'use strict';

document.addEventListener('DOMContentLoaded', () => {

  const dataBase = {
  books: [
  "Война и мир",
  "Крестоносцы",
  "Ивайло",
  "Чингиз-хан",
  "В глуби веков"
  ]
  };

  const bookList = document.querySelector('.book__interactive-list'),
  addForm = document.querySelector('form.add'),
  addInput = addForm.querySelector('.adding__input'),
  checkbox = addForm.querySelector('[type="checkbox"]');

  const sortArr = (arr) => {
  arr.sort();
  };

  function createBooksList(books,parent) {
  parent.innerHTML = "";
  sortArr(books); /* сортируем список по алфавиту */

  books.forEach((book, i) => {
  parent.innerHTML += `
  <li class="book__interactive-item">${i + 1} ${book}
  <div class="delete"></div>
  </li>
  `;
  });

  document.querySelectorAll('.delete').forEach((btn, i) => {
  btn.addEventListener('click', () => {
  btn.parentElement.remove(); /* удаляем родительский элемент при клике на иконку */
  dataBase.books.splice(i, 1); /* удаляем элемент с индексом i из массива */
  createBooksList(books,parent); /* перестраиваем элементы списка чтобы обновить нумерацию */
  });
  });
  }

  createBooksList(dataBase.books, bookList); /* создаём список на странице на основе начальных данных массива */

  addForm.addEventListener('submit', (event) => {
  event.preventDefault();

  let newBook = addInput.value;
  const favorite = checkbox.checked;

  if (newBook) {

  if (newBook.length > 21) {
  newBook = `${newBook.substring(0,22)}...`;
  }

  if (favorite) {
  alert('Добавлено в закладки!');
  } /* если галочка у чекбокса стоит, значит true */

  dataBase.books.push(newBook);
  sortArr(dataBase.books);

  createBooksList(dataBase.books, bookList); /* создаём список на странице на основе обновлённых данных массива */
  }

  event.target.reset(); /* очищаем данные формы */
  });

});

Тестировать

КОММЕНТАРИИ (0)

ТЕГИ МАТЕРИАЛА
События, DOMContentLoaded
РЕЙТИНГ МАТЕРИАЛА (0.0 / 0)