Pull to refresh

Bootstrap Modal Iframe Костыль

Reading time3 min
Views21K

«Не надо, я сам»
Хромой Итальянец

Постановка задачи


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

Сразу дали понять, что партнёры, хоть и партнёры, но размещать у себя что-либо сложное не будут, то есть про jQuery забыли. Стандартное решение – iframe с минимальной функцией resize на голом JavaScript.



Картинки
Баннер по умолчанию:



Баннер при вызове всплывающего окна:



В качестве backend ASP.NET MVC всё в Azure, картинки в Storage, таблички в SQL. Последнее время Редмонд активно рекомендует в качестве frontend шаблон Bootstrap. Собственно, никто и не против, так как по сравнение с тем, что предлагалось раньше, Bootstrap это просто праздник.

Основная проблема реализации – всплывающее окно из iframe перекрывающее по высоте родителя. На своём сайте можно спокойно вызвать Modal через parent iframe’а, но в данном случает домен у iframe другой и браузер будет защищаться. То есть CORS. Партнёры весело и дружно правящие конфигурации на своих веб серверах постановкой задачи не предполагаются.
Если нельзя трогать партнёрские сайты, то можно трогать наш iframe.

Решение


Костыль: в фоне под открывшимся Modal окошком увечить высоту iframe так, чтобы Modal помещался целиком или почти целиком.

Реализация


На HTML5 API window.postMessage. Есть несколько библиотек на jQuery, декларирующих динамический resize ifram’а. Но, во-первых, это предполагает подключение библиотек на стороне партнёрских сайтов, во-вторых в данной задаче надо совсем немного, а в-третьих, при проверки эти библиотеки не справились с учётом Modal окошка.

HTML нашего iframe’a
<div class="container" id="mainContent">
    <div class="row"><h1>Some iframe</h1></div>
    …
    <a href="#" class="btn btn-default" id="openBtn">Open modal</a>
</div>
<!--Большое Modal окно-->
<div id="myModal" class="modal fade" tabindex="-1" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content" id="myModalContent">
            …
        </div>
    </div>
</div>

JavaScript iframe’a onLoad
//Запуск Modal окошка
    $('#openBtn').click(function () {
        $('#myModal').modal({ show: true })
    });
//При открытии Modal окна отправляется сообщение с высотой Modal окна
    $('#myModal').on('shown.bs.modal', function (e) {
/*Звёздочку * здесь надо ставить, так как домен партнёрской страницы нам не известен и передаётся не секретная высота окна*/        
parent.postMessage($("#myModalContent").height(), "*");
    });
//При закрытии Modal окна отправляется сообщение с высотой без Modal окна
    $('#myModal').on('hidden.bs.modal', function (e) {
        parent.postMessage($("#mainContent").height() + 1, "*");
    });
//Установка начальной высоты iframe (+1 – на поля)
    parent.postMessage($("#mainContent").height() + 1, "*");


Полный код для iframe на Bootply

HTML на стороне партнёров
<iframe id="myIframe" src="http://bootply.com/render/112265" width="100%" scrolling="no"></iframe>


JavaScript на стороне партнёров вот тут товарищ сделал компактно

var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
eventer(messageEvent, function (e) {
//проверка на соответствие домена    
if (e.origin !== "http://www.bootply.com")
 retrurn;
//непосредственно resize
document.getElementById('myIframe').style.height = e.data + 'px';
}, false);


Полный код на стороне партнёров на Jsfiddle

На Jsfiddle подгружается iframe из Bootply, но Bootply заворачивает в ещё один iframe, который надо убрать (см. рисунок).

Неплохо также добавить общий resize:
$(window).resize(function () {
//но с проверкой на открытый Modal
if ($('#myModal').hasClass('in') == false)
parent.postMessage($("#mainContent").height() + 1, "*");
});


Полноэкранный результат, но надо снова
убрать bootply iframe.



Вывод



HTML5 подарил нам вполне рабочий костыль применимый в живом бизнес сценарии, где конечный пользователь сможет детально изучить предлагаемый ему товар, а торговая федерация заказчика с его партнёрами предположительно повысит динамику накопления фин ресурсов.
Tags:
Hubs:
0
Comments17

Articles

Change theme settings