TGViewer
Гипер Новости Гипер Новости @giper_news · 451 subscribers
Post #219 587
У нас тут под Новый Год большое обновление малой кровью. А именно импрув $mol_pop - компонента для показа контекстных всплывашек.

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

Тут-то и выходит на сцену $mol_pop, на базе которого у нас работают все пикеры - он открывает небольшое окошко (Bubble) рядом с якорным компонентом (Anchor). В случае пикера, якорем выступает кнопка его открытия (Trigger).

10 лет у нас была простая и надёжная реализация - бабл располагался рядом с якорем и через CSS позиционировался как надо. Работало просто, быстро, надёжно. Но есть с такой реализацией одна беда - его надо было аккуратно позиционировать, иначе он мог быть обрезан из-за overflow или z-index, так как рендерился там же, где и располагался в доме - рядом с якорем.

Типичное решение этой проблемы - порталы, то есть вынос бабла в корень (body), чтобы он рендерился на отдельном слое поверх всего интерфейса. Но у этого подхода есть две беды:

- Так как он больше не располагается рядом с якорем, мы не можем простым css его позционировать рядом с ним. Эту проблему призван решить css-anchoring, но у него ещё слабая поддержка.

- Так как он выносится из компонента-владельца, то его содержимое невозможно стилизовать используя составные селекторы, включающие имя владельца. А на этом у нас построена вся стилизация.

- По той же причине, компонент-владелец перестаёт получать события от бабла, что требует хитрых костылей с их перекидыванием.

К счастью, сейчас уже добралась до всех браузеров поддержка Popover API, предназначенного как раз для реализации всплывашек. Просто ставим на бабл атрибут popover="manual" и... ничего не меняется.

Оказыается, надо императивно вызвать затем метод showPopover(), чтобы браузер создал отдельный топовый слой и перенёс рендеринг бабла туда. hidePopover() же, наоборот, переносит рендеринг обратно (нейминг, конечно, божественный, да), но нам он и не нужен, так как баблы у нас рендерятся лишь когда начинают показываться, а когда перестают - удаляются нафиг, чтобы не тратить ресурсы впустую.

Так как бабл в доме остаёются внутри владельца, рядом с якорем, то CSS и события работают как надо. А вот позиционирование, из-за рендеринга в отдельном топовом слое, тут уже приходится реализовывать вручную.

Благо, у нас уже есть компонент $mol_follower, который отслеживает позицию якоря в реальном времени и позиционирует себя так, чтобы оказаться рядом с нужной стороны.

Так что я скрестил ужа с ежом и.. вроде получилось. Давайте потестим. Из компромиссов:

- В устаревших браузерах бабл может обрезаться.

- При скроллинге, бабл на несколько кадров отстаёт от якоря. В будущем переведём $mol_follower на css-anchoring и это пройдёт.
  • 🔥 7
  • 🎄 5
  • ☃ 2
  • ❤ 1
More from @giper_news
  1. Sep 24, 2026В начале октября я отправляюсь в Переславль-Залесский на конференцию разработчиков свободн…
  2. Sep 8, 2026Channel name was changed to «Гипер Новости»
  3. Sep 8, 2026Post #235
  4. Aug 30, 2026Post #234
  5. Aug 21, 2026Гипер Новости pinned a photo
  6. Aug 21, 2026Гипер Новости pinned «🟢 Актуально Новая старая вакансия Для рефакторинга на $mol научных…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →