Как исправить ошибку скрипта Tilda при переносе кнопки закрытия в попап
При разработке на платформе Tilda часто возникают сложности с кастомизацией стандартных компонентов. Одна из типичных задач - перенести кнопку закрытия .t-zoomer__close внутрь контейнера .t-carousel__zoomer__wrapper при клике на миниатюру галереи. В исходном коде новичка встречается ошибка Uncaught ReferenceError: block is not defined, которая полностью блокирует работу скрипта. Разберём причины и предложим рабочее решение.
Почему возникает ReferenceError: block is not defined
Ошибка возникает из-за того, что переменная block объявлена внутри функции обратного вызова события load. В JavaScript ключевые слова const и let имеют блочную область видимости. Это означает, что переменная block доступна только внутри функции, где она объявлена. При попытке обратиться к ней из консоли браузера (глобальная область) вы получаете ошибку not defined. Кроме того, вложенные обработчики событий и вызов insertBefore с некорректными ссылками могут приводить к неожиданному поведению.
Как правильно организовать перенос кнопки в Tilda
Для решения задачи нужно переписать скрипт, используя делегирование событий и правильные селекторы. Основная идея: навесить один обработчик на документ или на родительский контейнер галереи, который будет срабатывать при клике на любой элемент с классом .t603__blockimg. После открытия попапа (который создаётся стандартными средствами Tilda) необходимо переместить кнопку закрытия в нужное место.
Рабочий код скрипта для Tilda
Вот исправленный вариант, который корректно выполняется и не вызывает ошибок:
document.addEventListener('click', function(e) {
var target = e.target.closest('.t603__blockimg');
if (!target) return;
setTimeout(function() {
var wrapper = document.querySelector('.t-carousel__zoomer__wrapper');
var closeBtn = document.querySelector('.t-zoomer__close');
var img = document.querySelector('.t-carousel__zoomer__img');
if (wrapper && closeBtn && img) {
wrapper.insertBefore(closeBtn, img);
}
}, 300);
});Этот скрипт использует делегирование: клик отслеживается на всём документе, но действие выполняется только если кликнули по миниатюре. Задержка setTimeout в 300 миллисекунд нужна, чтобы дождаться открытия попапа Tilda (анимация может занимать время). После этого кнопка закрытия переносится перед изображением внутри .t-carousel__zoomer__wrapper.
Почему скрипт перестаёт работать сразу после вставки
Помимо ошибки видимости, исходный код содержит несколько логических проблем: во-первых, обработчик load срабатывает один раз, но при этом внутри него перебираются все элементы .t603__blockimg и для каждого создаётся отдельный обработчик. Во-вторых, при клике на любую миниатюру код пытается вставить кнопку во все найденные обёртки .t-carousel__zoomer__wrapper (их может быть несколько на странице), что приводит к дублированию или ошибкам. Исправленный скрипт работает только с одним активным попапом.
Особенности работы с Tilda и DOM
Платформа Tilda динамически генерирует HTML-структуру, поэтому элементы могут появляться после загрузки страницы. Используйте делегирование событий и проверяйте наличие элементов перед манипуляциями. Также рекомендуем оборачивать скрипт в script с атрибутом defer или размещать его перед закрывающим тегом </body> - это гарантирует, что DOM готов к работе.
Часто задаваемые вопросы
Ниже собраны типичные вопросы, которые возникают у разработчиков при решении подобной задачи.