Последняя лабораторная работа
Задача этой лабораторной работы – реализовать механизм, позволяющий делать такое: https://yhaskell.github.io/simple-data-binding/
Data binding – механизм, позволяющий "связать" данные модели с интерфейсом пользователя.
Этот механизм широко используется при построении графических интерфейсов: WPF, Angular, Vue.js, и многие другие библиотеки используют data binding.
Data binding разделяют на два типа: one-way и two-way. И тот, и другой вид обеспечивает синхронизацию модели и интерфейса; но одностороннее связывание обеспечивает синхронизацию только в одну сторону (интерфейс по модели, или модель по интерфейсу), в то время как двустороннее связывание, очевидно, делает и то, и другое.
Document Object Model (DOM) -- это программное представление графического интерфейса web-страницы, не зависящее от языка и платформы. Любой HTML-документ можно представить в виде дерева узлов, где каждому HTML-тэгу соответствует узел в DOM-дереве.
В JavaScript все DOM-элементы являются наследниками класса HTMLElement.
Так, элементу <div> соответствует класс HTMLDivElement, элементу <input>
соответствует класс HTMLInputElement, и так далее.
Более подробно связь тэгов и классов можно посмотреть, к примеру,
здесь.
DOM Traversal, или "навигация по DOM" – способ поиска конкретных элементов внутри дерева документа.
Корневым элементом DOM-дерева является элемент document, и у него, как и у других
элементов DOM-дерева, имеются следующие поля:
- 
childNodes– набор детей текущего узла. Включает в себя как элементы, так и текст
- 
children– набор детей текущего узла. Включает в себя только элементы (т.е. не текст, а только дочерние тэги)
- 
firstChild– первый ребёнок
- 
lastChild– последний ребёнок
- 
localName– имя тэга. (_Если узел текстовый, то это значение равно#text)
- 
parentElementилиparentNode– родитель
- 
nextSiblingиpreviousSibling– следующий и предыдущий родственник. Включает в себя как элементы (тэги), так и текстовые узлы.В случае <p><span>test</span> hello</p>следующим родственником тэгаspanбудет текстовый узел"hello"
- 
nextElementSiblingиpreviousElementSibling– аналогично предыдущему, но только для элементов (тэгов).
Ручной поиск элементов – не всегда удобный и быстрый способ найти элемент в дереве. Поэтому в реальном мире часто используются следующие функции:
- document.getElementById(id)из всего дерева выбирает элемент c соответствующим- id;
- el.querySelector(selector)выбирает из детей элемента- elпервый элемент, удовлетворяющий CSS-селектору, переданному в качестве параметра.
- element.querySelectorAll(selector)работает аналогично предыдущей функции, но возвращает массив всех элементов.
CSS-селекторы позволяют из множества элементов более узкое множество. Подробно про них можно прочитать здесь.
Наша библиотека преставляет интерфейс в виде класса Mount.
Конструктор класса Mount принимает два параметра -- mount (HTMLElement) и initial (object).
При инициализации наша библиотека обходит детей элемента mount, и начинает следить за изменениями
в тех элементах, в которых есть аргумент data-bind. Параметр initial используется для того, чтобы указать
начальное значение модели.
Объекты типа Mount имеют следующие публичные методы:
- subscribe(fn)принимает параметром функцию с двумя параметрами- key, valueи добавляет её во внутренний список подписчисков. При изменении модели все подписчики уведомляются об изменениях (- keyи- valueсодержат ключ и новое значение);
- set(key, value)устанавливает значение в модели по ключу- key;
- get(key)возвращает значение модели по ключу;
- toObject()возвращает всю модель как объект (изменения в этом объекте не должны менять модель).
Реализовать библиотеку, осуществляющую связывание данных для элементов input, select и span (1-way).
Библиотека должна соотвестствовать описанию в предыдущем пункте.
Для тестирования возьмите файл index.html из текущего репозитория и замените mount.min.js своей реализацией.
- Большинство DOM-объектов для элементов <input>и<select>содержат значение в полеvalue
- DOM-объект для флажка (<input type="checkbox">) содержит значение в полеchecked
- DOM-объект для куска текста (<span>) содержит значение в полеinnerText
- Текстовые поля при изменении выполняют событие oninput
- Флажки, и другие выборные элементы при изменении выполняют событие onchange
- Для регистрации обработчкиов событий существует функция element.addEventListener