Остановка видео при закрытии

Featherlight — лёгкая библиотека для создания модальных окон (lightbox) на базе jQuery. По умолчанию она отлично справляется с отображением изображений, HTML-контента и iframe, но при работе с видео возникает важный нюанс: видео не останавливается автоматически при закрытии модального окна. Это приводит к продолжающемуся воспроизведению звука, утечкам ресурсов и некорректному пользовательскому опыту.

Проблема особенно актуальна для:

  • видео в <iframe> (YouTube, Vimeo);
  • HTML5 <video>;
  • встроенных медиаплееров, инициализируемых через JavaScript.

Решение заключается в перехвате событий закрытия Featherlight и принудительной остановке воспроизведения.


Событийная модель Featherlight

Featherlight предоставляет набор событий жизненного цикла модального окна:

  • featherlight:opened
  • featherlight:close
  • featherlight:closed

Для остановки видео используется событие featherlight:close, которое срабатывает до удаления DOM-элементов, что позволяет корректно взаимодействовать с плеером.

Привязка выполняется через $(document).on(...), поскольку модальные окна создаются динамически.

$(document).on('featherlight:close', function(event){
    // логика остановки видео
});

Остановка HTML5 <video>

Если модальное окно содержит тег <video>, его можно остановить стандартными методами HTMLMediaElement.

<a href="#videoModal" data-featherlight>Открыть видео</a>

<div id="videoModal" style="display:none">
    <video controls>
        <source src="video.mp4" type="video/mp4">
    </video>
</div>

Обработчик закрытия:

$(document).on('featherlight:close', function(event){
    $('video').each(function(){
        this.pause();
        this.currentTime = 0;
    });
});

Ключевые моменты:

  • pause() останавливает воспроизведение;
  • currentTime = 0 сбрасывает позицию;
  • перебор необходим при наличии нескольких видео.

Работа с iframe и YouTube

iframe-видео не управляются напрямую через DOM API. Для YouTube применяется механизм postMessage.

Пример iframe:

<iframe
    src="https://www.youtube.com/embed/VIDEO_ID?enablejsapi=1"
    frameborder="0"
    allow="autoplay; encrypted-media"
    allowfullscreen>
</iframe>

Обязательное условие — параметр enablejsapi=1.

JavaScript-остановка:

$(document).on('featherlight:close', function () {
    $('iframe').each(function () {
        this.contentWindow.postMessage(
            '{"event":"command","func":"stopVideo","args":""}',
            '*'
        );
    });
});

Важно:

  • сообщение отправляется только в iframe с поддержкой API;
  • код безопасен при наличии других iframe, так как неподдерживающие его просто игнорируют сообщение.

Vimeo и универсальный подход

Vimeo также поддерживает postMessage, но с другим форматом команд:

$(document).on('featherlight:close', function () {
    $('iframe').each(function () {
        this.contentWindow.postMessage(
            JSON.stringify({ method: 'pause' }),
            '*'
        );
    });
});

Для проектов с несколькими источниками видео часто применяют универсальный обработчик, отправляющий команды всем iframe сразу.


Контекстное управление текущим окном

Featherlight передаёт объект экземпляра в событие, что позволяет ограничить область поиска видео только текущим модальным окном.

$(document).on('featherlight:close', function(event){
    var instance = event.target.featherlight;
    if (!instance) return;

    instance.$content.find('video').each(function(){
        this.pause();
        this.currentTime = 0;
    });

    instance.$content.find('iframe').each(function(){
        this.contentWindow.postMessage(
            '{"event":"command","func":"stopVideo","args":""}',
            '*'
        );
    });
});

Преимущества подхода:

  • не затрагиваются видео вне модального окна;
  • корректная работа при множественных Featherlight-окнах;
  • отсутствие побочных эффектов.

Использование callback-параметров Featherlight

Альтернативой глобальным событиям является передача callbacks при инициализации:

$.featherlight('#videoModal', {
    afterClose: function(){
        this.$content.find('video').each(function(){
            this.pause();
            this.currentTime = 0;
        });
    }
});

Метод удобен при точечном использовании, но менее масштабируем при большом количестве модальных окон.


Типичные ошибки и подводные камни

  • Отсутствие enablejsapi=1 у YouTube iframe делает управление невозможным.
  • Использование featherlight:closed приводит к ошибкам, так как DOM уже удалён.
  • Глобальный селектор $('video') без контекста может останавливать фоновое видео страницы.
  • Попытка управлять iframe через .pause() не работает.

Архитектурная рекомендация

Для учебных и производственных проектов оптимальной считается схема:

  • использование featherlight:close;
  • работа через instance.$content;
  • отдельная логика для <video> и iframe;
  • отказ от жёсткой привязки к конкретному провайдеру видео.

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