Проблема: дропдаун не меняет положения при ресайзе или изменении положения родителя. Касается также тултипов, поповеров и попапов.
- Чистые стили, только
reset.css
. - Позиционирование независимо от
overflow: hidden
.
- Кусок кода уезжает со своего места, порождая пачку проблем:
- Если там инпуты, они отрываются от формы, нужно следить за их заполнением и дублировать в hidden-поля.
- Если там подэлементы компонента, ломается поиск по JS-классам, ломается делегирование и слушание событий, нужно вводить специальные обёртки и кэшировать ссылки на них для каждого компонента, попавшего в дропдаун.
- Даже при отсутствии подэлементов ломается обычная событийная работа, потому что события всплывают прямо в
body
, минуя всех родителей. - Невозможно поместить дропдаун в элемент с
overflow: hidden
с обрезанием, если это всё же понадобится. Пример: дропдаун в попапе.
- Дропдаун никак не связан со свитчером, что порождает ещё одну пачку проблем:
- При изменении размеров окна свитчер может переехать, нужно обновлять его по событию
resize
(сделано). - При изменении положения свитчера (перед ним открылся ToggleBlock) нужно передвигать дропдаун, а это можно отследить только таймером.
- При изменении видимости любого из родительских элементов свитчера дропдаун нужно скрыть или показать, тоже отслеживается только таймером.
- Перемещение на JS по определению отстаёт и лагает, где-то больше, где-то меньше.
- (?) Перекрытие друг друга дропдаунами, тултипами, поповерами и попапами, которые произвольно насыпались в конец
body
. Перекрытие одного другим можно разрулить только черезz-index
, но дропдаун может открыться на странице под попапом и в самом попапе, в одном случае он должен быть под паранжой, в другом над паранжой.
- Переезжает сам вместе со свитчером, пока тот неподвижен относительно своего offsetParent'a. Если обернуть свитчер в элемент с
position: relative
, дропдаун будет переезжать вместе с ним при любом сдвиге и ресайзе нативно и без лагов. - Скрывается и показывается вместе с элементом при изменении видимости родителей.
- Элементы остаются на месте, находятся по дереву, события всплывают куда надо. Не требуется вмешательство в другие компоненты.
- Наследуются стили родителя, нужен сброс со стороны блока или специальная обёртка со стороны клиента. Вариант решения: g-reset.
- Если свитчер внутри элемента с
overflow: hidden
, дропдаун будет обрезаться. Вариант решения: в редких случаях помещения дропдауна с компонентами внутри вoverflow: hidden
по параметру осознанно переводить его в режим добавления вbody
и рефакторить попавшие в него компоненты.
Twitter, Google, Github кладут рядом. Яндекс кладёт в body и не следит за положением свитчера, можно подвинуть его стилями или поместив что-то перед ним, дропдаун остаётся на месте. При ресайзе на главной Яндекса дропдаун перерисовывается, а в картах нет.
См. скриншоты.
ХЗ. Проблемы те же, но выставить блок поверх всех остальных из любого места DOM не так-то просто.
Кто-нибудь приведёт аргументы против? А то я слышу только что это «ужастно и опастно» :) Объясните в чём проблема сброса наследуемых свойств (не всех).
Как ты позаботишься об этом, если скрипт умеет только в
body
или только рядом? Вот если он умеет и туда, и сюда, ты можешь позаботиться и указать ему правильный вариант для конкретной ситуации (если он отличается от дефолтного).Самая большая проблема второго способа в том, что если ты положил дропдаун рядом, уже ничего не сделаешь с
overflow: hidden
. Но это бывает не часто, и, если тебе не нужен доступ к элементам и событиям внутри, легко решается перемещением вbody
.Избежать проблем с
overflow: hidden
и с доступом внутрь одновременно не получится, поэтому и предлагаю переключатель. Второй способ предлагаю сделать дефолтным, потому что у первого полно других недостатков.