Skip to content
This repository was archived by the owner on May 6, 2025. It is now read-only.

Main Logic Deep

Pavel Motorin edited this page Aug 2, 2013 · 5 revisions

Main Logic Deeply Inside

Рассмотрим подробно всю цепочку событий с момента загрузки. Все модули пишутся в формате AMD и имеют, соответственно, прописанные взаимные зависимости.(…ссылку… на карту зависимостией)

Table of contents

Initialization

app — точка входа. Подключается на странице сайта. Инициализирует все приложение на основание файла config

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

На последнем шаге подгружаются модули sections, loader и clicks.

onClicks binding

При инициализации `clicks` вешает на единый обработчик на document.click, который срабатывает только в случае, когда таргетом события является ссылка (events генерится событие pageTransition:init, а само оригинальное событие (click) отменяется (evt.preventDefault()).

Section loading

На `pageTransition:init` подписан модуль `sections`, который содержит в себе общий менеджер переходов между страницами (transitions). Его работа основона на модулях [`sections/transition`](../blob/master/app/client/sections/transition.coffee), [`sections/loader`](../blob/master/app/client/sections/loader.coffee) и [`sections/cache`](../blob/master/app/client/sections/cache.coffee).

Происходит проверка, есть ли у нас в кэше уже нужная запись с url, и если есть, то просто создается новый объект перехода (transition) на базе соответствующей информации из кэша.

Если в кэше нет подходящих данных, то вызывается sections/loader, который призван подгрузить секции с сервера. После подгрузки он генерит событие sections:loaded с данными о загруженных секциях. В реакции на это событие текущий модуль sections создает новый объект перехода на основании этих загруженных данных.

Transitioning and Invoking

Каждый отдельный переход — это сущность, определяемая модулем `sections/transitions`.

На вход модуль конструктор получает данные о новых секциях, которые надо вставить, пропускает их через парсер sections/parser и отдает модулю sections/invoker, который и осуществляет непосредственную замену секций в DOM.

Invoker на основании данных про новые секции строит пары отдельных объектов типа Section (sections/section). Один элемент в паре — секция, которую надо вставить в конкретное место в DOM. Второй элемент — секция, которая заменится этой вставкой (вынется из DOM). Каждая секция сама себя вставляет или вынимает, генеря при этом событие section:inserted или sections:removed, соответственно. Если секция была объявлена в рамках какого-то пространства имен, например, popup, то будут созданы дополнительные события вроде section-popup:inserted. К каждому такому событию приложены данные о конкретной секции.

Invoker после окончания замены всех секций также генерит общее событие sections:inserted. Также Invoker следит за тем, чтобы секции не забыли включить все свои виджеты при вставки и выключить при удалении.

Widgets initializing

Все пользовательские скрипты на сайте пишуется в соответствие с заявленным [интерфейсом](Widgets) виджетов. [`widgets`](../blob/master/app/client/widgets.coffee). Их инициализация может происходит на уровне Section Loading. Loader получив HTML для вставки (или в случае первого входа на страницу, весь html целиком) пропускает innerHTML через специальный парсер ['widgetsData'](../blob/master/app/client/utils/widgetsData.coffee). Парсер ищет html-атрибуты `data-js-widgets` и возвращает набор пар node:widgestList. Если такой набор есть, то `sectionLoader` дальше предлагает модулю widgets создать на базе этого набора нужные виджеты: загрузить JS-файлы, создать на базе них виджеты и инициализировать их в контексте связанной ноды.

Таким образом все пользовательские скрипты знают в рамках какого html-блока они работают. На базе одного и того же js-файла виджета может быть создано несколько виджетов, если такие указания есть у разных узлов. Все эти виджеты будут обладать своим DOM-контекстом.

Напомним, что Invoker выключает связанные виджеты при вынимании секций со страницы (связанные виджеты — все, которые есть внутри DOM этой секции), и включает их при возвращении этой секции обратно на страницу. (back/forward из браузерной навигации).

Finish steps

… здесь чуть позже будет про нюансы с кэшированием ...

Bonus track: History

`window.history` в расширенном внутреннем варианте [`history`](../blob/master/app/client/history.coffee) проходит полосой сквозь многие модули. Бессмысленно говорить о подгрузке секций на лету, если мы не можем делать `pushState`. Поэтому `clicks`, `sections/loader` и другие даже не инициализируются, если в браузере недоступен window.history.

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

Clone this wiki locally