Как исправить ошибку скрипта 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 готов к работе.

    Часто задаваемые вопросы

    Ниже собраны типичные вопросы, которые возникают у разработчиков при решении подобной задачи.

    Часто задаваемые вопросы