Featherlight — лёгкая библиотека для создания модальных окон на базе jQuery. Одним из её преимуществ является гибкость в работе с различным контентом, включая изображения, HTML-элементы и iframe. Работа с iframe требует особого внимания из-за особенностей безопасности и динамического изменения размеров.
Для корректной работы с iframe требуется подключение jQuery и самой библиотеки Featherlight:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<link href="https://cdn.rawgit.com/noelboss/featherlight/1.7.14/release/featherlight.min.css" rel="stylesheet">
<script src="https://cdn.rawgit.com/noelboss/featherlight/1.7.14/release/featherlight.min.js"></script>
Инициализация модального окна с iframe осуществляется следующим образом:
$('.open-iframe').featherlight({
iframe: 'https://example.com',
iframeWidth: 800,
iframeHeight: 600
});
Здесь iframeWidth и iframeHeight определяют
размер модального окна. Это важно для корректного отображения стороннего
контента и предотвращения горизонтальной или вертикальной прокрутки.
Иногда необходимо ограничивать или фильтровать содержимое
iframe в зависимости от URL или других параметров. Featherlight
предоставляет возможность кастомизации через beforeOpen и
afterContent колбэки.
$('.open-iframe').featherlight({
iframeWidth: 800,
iframeHeight: 600,
beforeOpen: function(event){
var url = $(this).data('url');
var allowedDomains = ['example.com', 'trustedsite.org'];
var domain = (new URL(url)).hostname;
if (!allowedDomains.includes(domain)) {
alert('Доступ к этому ресурсу запрещён.');
return false; // блокирует открытие модального окна
}
this.$instance.find('iframe').attr('src', url);
}
});
Ключевые моменты:
beforeOpen позволяет перехватить момент перед открытием
модального окна.URL обеспечивает базовую защиту
от загрузки нежелательного контента.false отменяет открытие модального окна.Контент iframe может иметь непредсказуемую высоту. Для корректного
отображения рекомендуется использовать afterContent:
$('.open-iframe').featherlight({
iframeWidth: 800,
afterContent: function(){
var iframe = this.$instance.find('iframe');
iframe.on('load', function(){
try {
var height = iframe[0].contentWindow.document.body.scrollHeight;
iframe.css('height', height + 'px');
} catch(e) {
iframe.css('height', '600px'); // fallback
}
});
}
});
Объяснение:
afterContent выполняется после вставки контента в
окно.load позволяет дождаться полной
загрузки страницы внутри iframe.try-catch необходим для обработки ошибок при
кросс-доменных iframe, где доступ к contentWindow.document
запрещён политикой безопасности.Иногда требуется передавать параметры динамически:
$('.open-iframe').featherlight({
iframeWidth: 800,
iframeHeight: 600,
beforeOpen: function(){
var userId = $(this).data('user-id');
var url = 'https://example.com/profile?id=' + encodeURIComponent(userId);
this.$instance.find('iframe').attr('src', url);
}
});
Особенности:
encodeURIComponent предотвращает ошибки
при наличии спецсимволов.Featherlight не контролирует контент iframe напрямую, но можно использовать sandbox-атрибут для ограничения:
$('.open-iframe').featherlight({
iframeWidth: 800,
iframeHeight: 600,
afterContent: function(){
this.$instance.find('iframe').attr('sandbox', 'allow-scripts allow-same-origin');
}
});
sandbox запрещает всплывающие окна, формы и другие
потенциально опасные действия.allow-scripts,
allow-same-origin) даёт тонкую настройку разрешений.Для интерактивных приложений полезно закрывать модальное окно по событию из iframe:
$('.open-iframe').featherlight({
iframeWidth: 800,
iframeHeight: 600,
afterContent: function(){
var iframe = this.$instance.find('iframe')[0];
window.addEventListener('message', (event) => {
if (event.source === iframe.contentWindow && event.data === 'closeModal') {
this.close();
}
});
}
});
Пояснение:
postMessage для безопасной коммуникации
между iframe и родительским окном.event.source гарантирует, что сообщение пришло
от нужного iframe.afterContent и событие load, чтобы избежать
скроллинга.Если потребуется, можно детализировать работу с множественными iframe одновременно, включая фильтрацию, динамическое позиционирование и управление событиями между ними. Это особенно важно для сложных приложений с модальными окнами и внешним контентом.