
«Не надо, я сам»
Хромой Итальянец
Постановка задачи
Предлагается следующий сценарий: заказчик хочет разместить на сайтах своих партнёров небольшой горизонтальный динамический баннер с некой бизнес логикой, несложная калькуляция, табличка, локализация. Помимо этого, требуется всплывающее окно с крупной картинкой и контентом, которые по высоте больше чем родительский баннер.
Сразу дали понять, что партнёры, хоть и партнёры, но размещать у себя что-либо сложное не будут, то есть про 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 подарил нам вполне рабочий костыль применимый в живом бизнес сценарии, где конечный пользователь сможет детально изучить предлагаемый ему товар, а торговая федерация заказчика с его партнёрами предположительно повысит динамику накопления фин ресурсов.