Кармавьюер как слабо связанный модуль к HabrAjax

в 6:10, , рубрики: ajax, greasemonkey, метки:

Кармавьюер как слабо связанный модуль к HabrAjaxМодуль — это независимый плагин, который может работать без основного скрипта. История данного Кармавьюера начинается с 23 марта 2010 — автор Atilla написал скрипт показа кармы по наведению мыши на имя пользователя. К этому времени существовали другие 2-3 реализации показа кармы и одна — даже с изменением без захода на страницу. Идея быстрого и лёгкого просмотра кармы и рейтинга с использованием сайтового API показалась интересной и быстро была развита до поддержки всех браузеров. После разрушительной смены дизайна и вёрсток страниц в октябре 2011 все кармавьюеры и многие другие скрипты вымерли, как динозавры. Необходимости в кармавьюере не было, потому что скрипт HabrAjax и его предок умели показывать персональную страницу пользователя в фрейме половинной высоты. Загружается дольше, но и содержит больше информации. Реанимирование скрипта показа кармы было отложено на далёкий срок начала интеграции разных скриптов под управлением одного общего. Такое время пришло. Появились скрипты-модули, которые могут работать как независимо, так и интегрироваться с общим. Скачать кармавьюер.

Первый скрипт-модуль — это HabrPercentageRing — показ долей положительных и отрицательных оценок на кольцевой диаграмме вокруг числа общей оценки. Для связи между модулями он использует довольно новый вариант механизма пользовательских событий — CustomEvent. Отличается от обычного тем, что передаёт параметр-элемент DOM, которого как раз не хватало для указания места действия скрипта. Обработчики из модулей обращаются к элементу DOM как к контексту. Что будет, если понадобится передавать группу параметров? Придётся их передавать традиционным способом, через общие переменные в localStorage. Ещё можно создать несколько событий, по параметру DOM на каждое.

Для кармавьюера нужен тоже один параметр — контекстный DOM-элемент, в котором слушатель расставит свои обработчики. Поэтому он автоматически вписывается в систему, как говорится, слабо связанных модулей. Он может работать независимо, но если на странице есть источник событий «chgDom» — он подключается к обработке.

Особенности показа данных

* Данные для одной и той же ссылки читаются с сервера не чаще раза в 60 с (по наведению мыши), по рекомендации API: habrahabr.ru/info/help/api/.
* показ активируется на 4 типах ссылок на пользователей: на подписи к статье, на ссылке читателя в текстах и в правой колонке, в комментариях, в ответах на вопросы.
* блок подсказки фиксируется на странице кликом мыши, не исчезая по отведению. Повторный клик возвращает блок в исходное состояние — исчезновение при отведении мыши.
* Все показатели округлены до 0.1
* Быстрое проведение мыши над именем (менее 250 мс) не приводит к запросу показателей.
* цветами подложки отражаются 4 интервала значений кармы: ██ до -5, ██ -5: 9.9, ██ 10: 24.9, ██ 25 и более.
* если при получении данных произошла ошибка (например, нет связи или сервер не отвечает), повторного запроса нет.

«Что-то мне знакомое, так-так»

А теперь рассмотрим способ построения пользовательских событий на уровне языка разработки, применённый в этом модуле.

События — это довольно легко моделируемая сущность, которую можно представить как список процедур, который генераторы событий пополняют, а слушатели — исполняют. Имеем 2 вида команд: источники (генераторы) и приёмники (слушатели). Если для события не найдётся слушателя, никто, ни один скрипт не будет впадать в истерику и останавливать всю ветвь. Это называется «слабая связанность процедур»: есть предложения процедуры продолжить, но ничего не случается, если продолжать некому.

Как для всех других процедур, события имеют аргументы. Как для других процедур, события имеют имена.

Чтобы выполниться, список событий должен периодически пересматриваться слушателями. Для этого существует процедура — контроллер событий, если мы её напишем. Дёргать контроллер на исполнение могут сами события, поступающие от генераторов. Пробегаем список слушателей и ищем знакомое имя.

Да, система хорошая, но при некотором объёме она начнёт занимать много ресурсов. Для быстроты работы, в язык начали включать встроенные пользовательские события. Вспомним, что встроенные события от окружения программ и устройств уже были. Теперь появилась возможность делать события, очень похожие на встроенные, настолько, что программы отличить уже не могут и даже слушатели встроенных событий на них реагируют.

Появились и чисто пользовательские события. Для начала — без аргументов. Но вскоре они понадобились, и программистам выделили потренироваться один полноценный аргумент в событиях CustomEvent. Полноценность означает, что он может быть любым объектом или DOM-объектом. Если нужно больше? Вспоминайте устройство событий — и вперёд. Или нет, на единственный аргумент уже можем повесить хеш, а в него — сколько угодно ключей. Устроит?

Давайте разберём работу событий CustomEvent, чтобы узнать, какие удобства они дают и какие неудобства с поддержкой относительно старых браузеров (ОСБ) получаем (IE7, Fx3.6-Fx5).

Довольно часто ОСБ нужно поддерживать, поэтому вопрос: отказаться от нового типа события или сделать оба вида поддержки? Если передавать нужно примитивы, то легко реализовать старое событие (если оно единственное в системе, выделяем ему переменную в хранилище для аргументов).

Если передавать нужно DOM-объект, то всё сложнее. Нужно через строку описать, какой объект передаём и положить строку в общедоступное место, например, в localStorage. Нам в событиях при взаимодействии модулей нужно передавать DOM-объект — блок, контекст, в котором действует событие. Может быть, понадобится и сложнее. Если обойтись поддержкой DOM-объекта в ОСБ, то нужна всего лишь запись доступа к элементу через DOM, если это возможно. Если невозможно — придумываем место в DOM, куда кладём аргумент или аргументы.

Такова цена поддержки ОСБ. Иногда аргументы поддержатся, иногда понадобится придумывать более сложный способ поддержки. Поскольку задачи обычно не очень глобальны, можем решать частные задачи, ожидая, когда ОСБ превратятся в ОчСБ.

Автор: spmbt


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js