Перейти к содержимому
Забрать бесплатно
Модификации выключены. Так эта страница выглядит на обычной Тильде.
РАЗБОР · 10 ТИПОВ ЭЛЕМЕНТА · 354 ЭЛЕМЕНТОВ · 5 СТРАНИЦ

Зеро блок в Тильде: десять типов элементов, и почему аккордеона среди них нет

Зеро блок — единственный блок Тильды, где элементы стоят на свободном холсте. Эта страница собрана не из справки, а из двух источников, которые можно проверить: разметки пяти страниц, собранных самой Тильдой, и кода её рантайма. Перепись — 354 элемента в 39 артбордах. Набор типов элемента взят не по памяти, а из развилки в коде: она перечисляет ровно десять значений и не имеет ветки «всё остальное».

Короткий ответ

пятьдесят слов

Зеро блок (Zero Block, блок T396) — блок Тильды, где элементы стоят на свободном холсте, а не в готовой сетке. Рантайм собирает в нём ровно десять типов элемента: текст, фигуру, картинку, кнопку, видео, HTML-код, подсказку, форму, галерею и вектор. Аккордеона, табов, таймера и карты среди них нет — их кладут внутрь элемента HTML-кода.

Десять типов из развилки в коде

Каждый элемент внутри артборда несёт атрибут data-elem-type. Рантайм читает его и по нему выбирает, какую функцию позвать — это обычная развилка switch в файле tilda-zero-1.1.min.js. Развилка перечисляет десять значений, и ветки «всё остальное» у неё нет. Поэтому десять — закрытый список, а не «столько удалось вспомнить».

data-elem-type Что это Раз Доля Чем занимается рантайм
text Текст 169 47.7% Единиц высоты в списке полей нет. Режим по умолчанию рантайм подставляет сам — "text"===d&&(c="autoheight"), — и в режимах autowidth/autoheight/singleline высоту отдаёт браузеру: style.height="auto".
shape Фигура 82 23.2% Самый простой из десяти: получить узел, записать поля, перерисовать. Ни одного вызова наружу.
image Картинка 60 16.9% Высоты в полях нет вовсе — она выводится из пропорции файла: i=r/(parseInt(o)/parseInt(n)). Поэтому картинка единственная, кому рантайм пересчитывает положение по событию load, и ставит ещё один пересчёт через setTimeout на 2000 мс.
button Кнопка 34 9.6% Единственная из десяти возвращает узел. Поле caption в списке есть, а ветки case "caption" в перерисовщике нет — значение читается и выбрасывается. Режим по умолчанию — fixedsize.
video Видео 3 0.8% Поля как у фигуры. Всё видеоспецифичное — в отдельном файле, в ядре его нет. Работу передаёт наружу — t396_initVideo из tilda-zero-video-1.0.min.js.
html HTML-код 1 0.3% Побайтово та же функция, что у фигуры, только имя другое. Содержимое рантайм не трогает вообще: ставит рамку по тем же одиннадцати полям и уходит. Отсюда и практический смысл — это единственный из десяти типов, внутрь которого можно положить что угодно своё.
tooltip Подсказка 0 — Единственный тип с особой обработкой ширины: она копируется во все .tn-atom__pin-icon как width и height, а высота элемента приравнивается ширине, после чего ветка height для подсказки выходит сразу — if("tooltip"===d)return. Работу передаёт наружу — t396_initTooltip из не найден в корпусе.
form Форма 2 0.6% Высоты в полях нет. Описание полей формы лежит в JSON — либо в .value у .tn-atom__inputs-textarea, либо в data-value у .tn-atom__inputs-data. Перерисовка идёт дважды: до и после инициализации форм. Работу передаёт наружу — t_zeroForms__init из tilda-zero-forms-1.0.min.js.
gallery Галерея 0 — Самый особый из десяти. Единственный, кому размеры пишутся через calc(… * var(--zoom)) — белый список t396__isElementUsingCalcZoom состоит ровно из одного пункта, ["gallery"]. Единственный со своим сайзером и единственный, из-за кого в расчёте автовысоты появилась поправка на подпись, точки и стрелки. Работу передаёт наружу — t_zeroGallery__init из tilda-zero-gallery-1.0.min.js.
vector Векторная фигура 3 0.8% Поля как у картинки, только без img. Ни одного вызова наружу.

«Раз» и «доля» — из переписи пяти страниц, а не из справки. Восемь типов из десяти встретились хоть раз; tooltip и gallery — ни разу, хотя функции для них в рантайме есть.

Чего среди десяти нет и где это в Тильде на самом деле

Аккордеон, табы, бегущая строка, таймер обратного отсчёта, карта, квиз, поиск по сайту — ни одного из них в списке десяти нет. Формулировать это надо аккуратно, потому что напрашивающаяся фраза «в Тильде такого нет» неверна: шесть из этих семи в Тильде есть, просто не в зеро блоке. Ниже — что замер разрешает утверждать, а что нет.

Задача Есть в Тильде В зеро блоке Где это на самом деле
Аккордеон, раскрывающийся блок частично Как тип элемента — нет. Но «Читать далее» внутри текста рантайм Zero Block поддерживает сам: t396__intializeUndercut ищет в артборде .ql-undercut и подгружает под него скрипт (опечатка в имени — Тильдина). Аккордеон по категориям есть внутри T972, баннера cookie (t972__category-btn, поворот t972__line_horizontal на 180°). Сворачивание текста — tilda-undercut-1.0.min.js. Сворачивание дерева фильтров каталога — .t-store__filter-tree-children.is-collapsed.
Табы, переключение вкладок да Своих табов нет. Зато Zero Block умеет быть содержимым чужого таба: при data-connect-with-tab="yes" он слушает displayChanged и перерисовывается, когда его вкладку открыли. Форма внутри него делает то же самое. T817 — это и есть блок табов (role="tablist", data-tab-current, на мобильном вместо полосы select). Табы карточки товара — tilda-catalog-1.1.min.js плюс отдельный tilda-catalog-tabs-1.0.
Бегущая строка, тикер нет Нет — ни типа элемента, ни функции, ни имени класса. Нигде в рантайме. На живых страницах встречается, но всегда как рукописный код внутри T123 — то есть внутри блока «свой код», а не как блок Тильды.
Таймер обратного отсчёта частично Нет. Имя класса .t-timer не встречается ни в ядре, ни в двух его сателлитах. Блок-таймер у Тильды есть — его класс .t-timer зашит в ядро анимации tilda-animation-2.0.min.js наравне с .t-title и .t-btn, — но сам код блока в корпус не попал. Таймеры, которые попали, к отсчёту не относятся: «товар удалён, вернуть» в корзине T706 и таймер в попапе успешной отправки.
Карта да Нет. ymaps, t-map, api-maps отсутствуют и в ядре, и в сателлитах. Карту можно вставить только как содержимое элемента HTML — а он ничего не исполняет, его набор полей чисто геометрический. В рантайме ровно одна карта — Яндекс, и только для выбора пункта выдачи: tilda-delivery-1.0.min.js создаёт ymaps.Map в контейнере #delivery-yandex-map. Блок-карта у Тильды есть — автомасштабирование про .t-map знает и специально её не масштабирует, — но её код в корпус не попал.
Квиз, пошаговая форма да Нет. Форма в Zero Block одноэкранная: в её файле слово quiz не встречается ни разу, кнопок «дальше» и «назад» нет. Квизовая ветка включается по номеру записи 835 или 862, а Zero Block — запись 396, и в эту ветку не попадает. T835 и T862 — Тильда называет их сама: if(835==o||862==o) в tilda-forms-1.0.min.js, плюс t_forms__isQuiz по классу .t-quiz и кнопки t835__btn_next / _prev / _result.
Поиск по сайту да Нет, и Zero Block такой блок собой не заменяет. Ни t985, ни t838, ни data-search-target в ядре и сателлитах не встречаются. T985 — виджет поиска; Тильда сама называет номер блока в своём тексте ошибки: «На странице отсутствует виджет поиска (блок T985)». Оверлей и подсказки — в постраничном бандле, а само выполнение запроса уходит во внешний tilda-searchwidget-1.0.min.js с отдельного хоста search.tildacdn.com: поиск серверный, и в корпусе его быть не может. T838 — старая встроенная строка.

Единственная из семи задач, про которую замер разрешает сказать «в Тильде этого нет», — бегущая строка. Все тридцать вхождений слова marquee в корпусе объяснены до единого: перед каждым стоит -webkit-, это правило CSS-сброса. На живых страницах бегущая строка встречается — но всегда рукописным кодом в блоке «свой код», а не блоком Тильды.

В обратную сторону есть одна приятная неожиданность. «Читать далее» внутри текста — не самодельное: рантайм зеро блока сам ищет в артборде .ql-undercut и подгружает под него скрипт. И табы зеро блок хоть и не умеет создавать, но умеет быть их содержимым: при data-connect-with-tab="yes" он слушает displayChanged и перерисовывается, когда вкладку открыли, — иначе элементы в скрытой вкладке посчитались бы по нулевой ширине.

Единственный из десяти типов, внутрь которого можно положить что угодно своё, — html. Функция, которая его обслуживает, побайтово совпадает с функцией для фигуры: рантайм ставит рамку по одиннадцати полям и уходит, содержимое не трогает вообще. И вот замер, который стоит держать в голове: в 354 элементах пяти страниц Тильды элемент html встретился 1 раз — это 0.3% всех элементов, а текста, фигур и картинок — 88,8% на троих. Зеро блок в живой жизни используют как холст для вёрстки, а не как контейнер для своего кода.

Оговорка, без которой любое из этих отрицаний врёт: отсутствие в корпусе не равно отсутствию в Тильде. Тильда привязывает функции отложенно, через t_onFuncLoad, поэтому функция может вызываться в файле, который у нас есть, а определяться в постраничном бандле, которого нет. Замер «упоминается / определяется» это показывает прямо: t817_init — 2 упоминания и 0 определений, t972_init — 14 и 0. Такие предметы отмечены выше как «частично» или названы по имени блока без разбора кода.

Разрешения список принадлежит артборду

Общее место — «у Тильды пять разрешений: 320, 480, 640, 960 и 1200». Как утверждение о платформе это неверно, и проверяется одной строкой поиска по вашей же странице.

Список лежит в атрибуте data-artboard-screens у самого артборда. Числа 320, 480, 640, 960, 1200 рантайм подставляет только тогда, когда атрибута нет вовсе, — это запасной вариант, единственный числовой массив во всём файле ядра. В переписи 39 артбордов:

  • 320,480,640,960,1200 — 38 артбордов
  • 320,480,640,960,1440 — 1 артборд , и это rec1024570506 на tilda.cc

Тот единственный артборд с верхним значением 1440 стоит на собственной странице tilda.cc. То есть верхнюю границу меняет сама Тильда, и код, который рассчитывает на 1200, на такой странице считает не то.

Второе следствие, из которого ломаются поиски по разметке: значения полей для самого крупного разрешения лежат в атрибуте без суффикса. Рантайм так и читает — на максимальном разрешении берёт data-artboard-height, на остальных data-artboard-height-res-960 и так далее. Поэтому в корпусе суффиксов ровно столько:

Суффикс Атрибутов
-res-320 1689
-res-480 1574
-res-640 1542
-res-960 1480
-res-1200 0
-res-1440 0

Ноль у 1200 и 1440 — не пропуск в замере, а ровно то, что предсказывает код. Это и был контроль: сошлось.

Автовысота рантайм правит собственные данные

Артборд с автовысотой помечен data-artboard-heightmode="hug" — других значений рантайм не сравнивает. Дальше происходит то, чего от разметки не ждёшь: посчитав высоту, рантайм записывает её назад в то же поле, которое читает как заданную высоту. Порог записи — расхождение больше 0,7 пикселя.

Три следствия, каждое проверяемо по коду и каждое объясняет знакомую странность:

  1. Не все элементы увеличивают высоту. Из подсчёта исключены те, у которых отступ сверху или высота заданы в процентах, и те, что привязаны к низу или к центру. Такой элемент может свисать за край артборда, а автовысота его не заметит.
  2. Быстрый путь расчёта доступен только автолейауту. Он требует класса t396__artboard-flex; обычный артборд с абсолютным позиционированием всегда идёт длинным путём — перебором прямых детей. В переписи артбордов на автолейауте 22 из 39.
  3. Пересчёт идёт по таймеру всё время жизни страницы — раз в три секунды на каждый такой артборд, и снятия таймера в файле нет ни одного. Плюс ещё четыре источника пересчёта: готовность шрифтов, загрузка картинок и два наблюдателя за изменениями в поддереве.
Закрепление при скролле закрепляет не JS

За закрепление отвечает отдельный файл — tilda-zero-fixed-1.0.min.js, 3006 байт, 8 функций. Первое, что стоит про него знать: он не закрепляет. В файле нет ни position, ни transform, ни sticky, ни z-index. Всё, что он делает, — переключает три класса; сам position: fixed печатает в страницу публикатор Тильды, инлайновым правилом на конкретную запись.

Единственное событие, которое он слушает, — scroll, с ограничением в 200 миллисекунд. Единственное сравнение — текущая позиция скролла против числа из поля триггера. Из этого прямо следует то, что обычно выясняют опытным путём:

  1. Верхней границы нет — блок не отпускается никогда. Ни конца артборда, ни конца страницы в расчёте не участвует.
  2. Высота шапки не учитывается. Селектора шапки в файле нет вовсе, так что закреплённый блок и меню разъезжаются сами по себе.
  3. Нечисловой триггер прячет блок навсегда. Значение вида 50vh в сравнении даёт «не число», условие не выполняется ни при каком скролле, и блок остаётся в состоянии, где он не только невидим, но и не принимает клики.
  4. Прозрачный фон отменяет распорку под плашкой «Made on Tilda»: блок без фона выпадает из внутреннего реестра, и нижний закреплённый блок эту плашку накроет.

Сдвиг страницы вниз под закреплённой сверху шапкой — ещё один отдельный файл, tilda-zero-top-shift-1.0.min.js, и делает он ровно одну вещь: ставит padding-top у <body> равным высоте артборда. Ни в одной из пяти страниц корпуса он не подключён, и атрибута, который его включает, в разметке тоже нет ни одного — так что сказать о нём можно только то, что написано в его коде.

За что браться из кода 9 точек и 4 события

Файл ядра не обёрнут ни в модуль, ни в замыкание, поэтому формально глобальны все 99 его функций. Ниже — те, за которые есть смысл браться из своего кода, и состояние, которое можно прочитать вместо того, чтобы измерять заново.

Что Вид Зачем
window.tn.ab<recid> состояние Состояние одного артборда: screens, curResolution, curResolution_max, scaleFactor, canvas_min_width, canvas_max_width, grid_width, grid_offset_left.
window.tn.isEditMode состояние Открыт ли редактор. Ядро сверяется с ним перед тем, как ставить --zoom, — то есть в редакторе и на сайте геометрия считается по-разному, и это причина расхождений «в редакторе работает, на сайте нет».
window.tn_scale_factor состояние Глобальный коэффициент масштаба, без привязки к блоку. При двух Zero Block на странице здесь останется значение того, который инициализировался последним.
t396__getZeroBlocks() функция Возвращает массив { record, artboard } по всем Zero Block страницы — включая те, что в попапе.
t396__getCurrentScaleFactor(recid) функция Коэффициент масштаба блока. Осторожно: реализация падает на глобальный window.tn_scale_factor, если у нужного блока значения нет.
t396_ab__getFieldValue(artboard, field) функция Значение поля артборда с разрешением каскада по брейкпоинтам — то же, чем пользуется сам рантайм. Читать атрибуты руками смысла нет: каскад придётся повторять.
t396_core__getFieldValue(node, field) функция То же для элемента или группы: сам выбирает нужный геттер по классу узла.
t396_detectResolution(recid) функция Текущий брейкпоинт блока по его собственному списку screens.
t396__updateAutoHeight(artboard) функция Пересчитать автовысоту. Нужна, если модификация меняет содержимое hug-артборда.

События, на которые можно подписаться вместо опроса в setInterval:

  • artBoardRendered — на артборд, единственное всплывающее — можно слушать на document
  • artBoardResized — на артборд, не всплывает
  • zero:height-changed — на .t396, после того, как автовысота переписала поле
  • zero:window-width-changed — на document, ширина, не высота
Откуда числа 5 страниц Тильды

Перепись собрана по пяти сохранённым страницам. Две сделала сама Тильда, две — клиентский сайт на её платформе, одна собрана на автолейауте:

  • tilda.cc/ru/ главная Тильды, страница 75717 — 18 элементов в 2 артбордах
  • tilda.education/en/ её образовательный сайт, страница 145229936 — 118 элементов в 23 артбордах
  • smv-shop.ru/contacts клиентский сайт, страница 28337012 — 99 элементов в 5 артбордах
  • smv-shop.ru/test1234 его страница магазина, страница 141185516 — 39 элементов в 4 артбордах
  • mo-ti.ru страница на автолейауте, страница 9692335 — 80 элементов в 5 артбордах

Контроль замера. Зеро блок помечается в разметке четырьмя способами, и рантайм ищет по всем четырём: два атрибута, каждый со значением 396 или 121. Сумма по всем четырём — 38 + 1 + 0 + 0 = 39, — совпала с числом артбордов, найденных независимо, по классу. Значит пятого способа пометки в этих страницах нет.

Что этот контроль попутно вскрыл: зеро блок внутри попапа несёт data-record-type="2071", а зеро-блоком его делает второй атрибут — data-parenttplid="396". Практический вывод: селектор [data-record-type="396"] найдёт только те зеро блоки, что не в попапе. Это не догадка — рантайм сам ищет по обоим атрибутам, собирая селектор из двух половин.

Список из семи задач выше проверялся отдельным проходом — по 161 файлам, 16.5 МБ, каждая задача несколькими написаниями: номер блока, имя класса, английское слово, имя функции. Считались вхождения, а не строки: ядро зеро блока — одна строка в 44 395 байт, и построчный счёт вернёт на нём единицу при любом числе совпадений.

Контроль того прохода: заведомо существующее нашлось четырьмя независимыми написаниями — gallery 445 вхождений, tooltip 333, t396 31 468, data-elem-type 1592. И третья, независимая от кода проверка десятки: в 25 сохранённых страницах 1558 фактических значений data-elem-type дали ровно 9 различных — все из объявленных десяти и ни одного неожиданного. Плюс перепись самих функций: определений t396_add* ровно 10, и каждое имя встречается в файле по 2 раза — определение и единственный вызов. Других точек входа нет, подсунуть одиннадцатый тип неоткуда.

Чего на этой странице нет: списка «что можно сделать в зеро блоке». Это вопрос про редактор, а на руках у нас его вывод, а не его интерфейс — пять готовых страниц и код рантайма. Утверждать по ним, что показывает панель настроек, было бы домыслом.