dshovchko / practice-3

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Практическая работа 3: Классы, DOM, события

Начало работы

Установите зависимости проекта:

npm install

После этого вам будут доступны следующие команды:

  • npm run lint - проверка качества вашего кода утилитой ESLint
  • npm run test [test-file] - запустить unit-тесты из указанного файла в консоли, например: npm run test test/spec/task-1.spec.js
  • npm run test - запуск всех unit-тестов в консоли
  • npm run test:watch [test-file], npm run test:watch - запуск одного или всех unit-тестов в консоли, с автоматическим перезапуском при изменении исходного кода. Например: npm run test:watch test/spec/task-1.spec.js

Кроме того, для выполнения заданий связанных с DOM-деревом и событиями вам нужно тестировать ваш код в браузере. Для этого есть команда

  • npm run start - открывает в браузере страничку с необходимой для вашего кода разметкой. При изменении кода страничка автоматически перезагружается.

Задания

Задача 1

Декофеинизированная команда марсохода из второй практической работы решила проблемы с поступлением марсоходу бессмысленных команд и с порядком их получения. Заодно они решили сменить API управления марсоходом и сделать его в ООП-стиле.

Напишите класс Rover, который имеет следующий публичный интерфейс:

Метод Параметры Описание Дополнительно
constructor
  • x - начальная (целочисленная) x-координата ровера
  • y - начальная (целочисленная) y-координата ровера
  • direction - начальное направление движения ровера, одна из констант NORTH, EAST, WEST, SOUTH
Конструктор. Nuff said. Выбрасывает исключение TypeError если переданы не целочисленные координаты, или несуществующее направление движения
left - Поворот марсохода налево -
right - Поворот марсохода направо -
move n - (целочисленное) число шагов Движение на n шагов вперед. Может быть отрицательным. Выбрасывает исключение TypeError если передано не целочисленное число шагов.
getPosition() - Возвращает текущие координаты марсохода Формат: { x: 5, y: 6 }
getDirection() - Возвращает текущее направление Возвращает одно из значений NORTH, EAST, SOUTH, WEST

Кроме того, методы left, right, move должны быть "chainable", т.е. должны иметь возможность вызываться цепочкой:

const r = new Rover(0, 0, NORTH);
r.left().move(5).right().right().move(1);

r.getPosition(); // { x: -4, y: 0 }
r.getDirection(); // EAST

Задача 2

У стандартного класса Set есть фатальный недостаток. Ему недостаёт нескольких полезных методов.

  • union(s) - (объединение множеств) создать новое множество, куда входят все объекты из множества this и множества s
  • intersection(s) - (пересечение множеств) создать новое множество, куда входят только объекты, принадлежащие и this, и множеству s
  • difference(s) - (разность множеств) создать новое множество, куда входят объекты, принадлежащие this, но не принадлежащие множеству s
  • symmetricDifference(s) - (симметрическая разность) создать новое множество, куда входят объекты принадлежащие или this, или множеству s, но не обоим множествам одновременно
  • isSuperset(s) - функция, возвращающая true, если множество s вложено в множество this
  • isSubset(s) - функция, возвращающая true, если множество this вложено в множество s

Напишите класс EnhancedSet, который наследуется от Set, и расширяет его этими шестью методами.

Задача 3: Table Filterer

Представим что на дворе 2008 год, и попробуем попрограммировать в стиле jquery. Дана HTML таблица, каждая строка которой представлет одну запись из базы данных. Первая ячейка каждой строки - порядковый номер в таблице Некоторые ячейки содержат аттрибут data-field-name, в котором хранится имя поля из базы данных, которое отображается в этой ячейке.

Например:

<tr>
    <td>1</td>
	<td data-field-name="album">Fly on the Wall</td>
	<td data-field-name="performer">AC/DC</td>
	<td data-field-name="genre">hard rock</td>
	<td data-field-name="year">1985</td>
	<td><a href="http://www.wikidata.org/entity/Q901854">Link</a></td>
</tr>

Напишите функцию, filterTable, которая будет фильтровать строки таблицы по заданному условию. Она получает два аргумента: DOM-элемент с телом таблицы, и объект с фильтрами в виде <имя поля>: значение

Например:

{
    year: "1980",
    genre: "rock"
}

Этот фильтр должен оставить только те строки таблицы, в поле year которых содержится "1980", а поле genre содержит слово "rock" - i.e. "rock", "punk rock", "exotic instrumental post-rockabilly".

Функция filterTable должна:

  • Прятать не соответствующие фильтрам строки добавляя к соответствующему тегу <tr> класс d-none
  • Сохранять последовательную нумерацию строк, перезаписывая числа в первых ячейках строк
  • Сохранять "зебровую" раскраску таблицы - четные строки должны иметь класс table-row-even, у нечетных этот класс должен отсутствовать.
  • Быть независимой от порядка ячеек и имен полей в них, т.е. работать для любой таблицы с любыми именами полей в фильтруемых ячейках.

PS: Закройте глаза представьте что вам нужно было бы еще реализовать сортировку таблицы по значениям полей, обменивая строки внутри таблицы местами. Откройте глаза и с облегчением выдохните: вам не нужно этого делать. Возможно, вы заметили что такой jquery-style код трудно читать, поддерживать и изменять.

Задача 4: Shopping Cart

Представим что на дворе 2009 год, мы осознали что охапка функций в глобальной области видимости - это прошлый век и решили использовать самописный-наивный-прото-компонентный подход.

Напишите класс, который реализует функционал корзины покупок на сайте. В корзине есть следующие элементы:

  • Сообщение о том что список покупок пуст. Оно должно отображаться только в случае если пользователь не добавил ни одного товара.
  • Список товаров в корзине. Каждый раз когда пользователь нажимает на кнопку "Buy", товар добавляется в этот список. Если такой товар в списке уже есть, то количество этого товара в корзине увеличивается на 1, и изменяется общая цена для этого товара. У каждого товара есть кнопка "Remove", которая удаляет его из корзины (удаляются все единицы этого товара).
  • Общая сумма цен всех товаров в корзине. Изменяется каждый раз когда мы добавляем или удаляем товар из корзины.
  • Кнопка "Remove All", клик по которой полностью очищает корзину.

Некоторые методы этого класса уже написаны, некоторые реализованы частично, и у всех методов заботливо прописана документация в формате JSDoc, из которой вы можете узнать назначение метода, его параметры и возвращаемое значение. Вам остается всего лишь заполнить оставшиеся лакуны!

Прятать элементы можно с помощью класса d-none. Храните всю вспомогательную информацию только в сберегательных кассах data-атрибутах HTML-элементов: например, чтобы проверить существует ли в корзине товар с заданным id, нужно проверить существование в корзине HTML-элемента с соответствующим data-item-id.

Рекомендуемый порядок действий:

  • Начните с метода isCartEmpty
  • Реализуйте показ/скрытие сообщения о пустой корзине и кнопки "Remove All" в методах updateNoItemsMessage и updateRemoveAllButton.
  • Реализуйте проверку isItemInCart
  • Реализуйте метод incrementItem, увеличивающий количество товара, и общую сумму товара, если он уже добавлен в корзину. Не забудьте при этом обновить атрибуты data-item-qty и data-item-total, они вам пригодятся при последующих добавлениях товара и подсчете общей суммы всех товаров.
  • Кстати, вот теперь и реализуйте подсчет общей суммы всех товаров в методе getTotalSum и обновление этого числа в методе updateTotal.
  • В методе addEventListeners добавьте обработчик клика на кнопку "Remove All", который должен вызывать метод removeAll
  • Добавьте обработчики клика на кнопки "Remove" каждого товара в корзине, которые вызывают метод removeItem с соответствующим id. У вас есть два варианта решения: добавлять обработчик каждый раз когда добавляется новый товар в корзину, или добавить один обработчик на всех в методе addEventListeners, используя делегацию обработки событий.
  • Реализуйте методы removeItem и removeAll.

Представьте что вам нужно дополнить ваш класс: нужно добавить общее число купленных товаров внизу списка, по аналогии с Total Sum. Прикиньте число мест в вашем классе, в которые придется внести изменения.

About

License:MIT License


Languages

Language:JavaScript 79.8%Language:HTML 20.2%