- PVSM.RU - https://www.pvsm.ru -
«Не надо, я сам»
Хромой Итальянец
Предлагается следующий сценарий: заказчик хочет разместить на сайтах своих партнёров небольшой горизонтальный динамический баннер с некой бизнес логикой, несложная калькуляция, табличка, локализация. Помимо этого, требуется всплывающее окно с крупной картинкой и контентом, которые по высоте больше чем родительский баннер.
Сразу дали понять, что партнёры, хоть и партнёры, но размещать у себя что-либо сложное не будут, то есть про jQuery забыли. Стандартное решение – iframe с минимальной функцией resize [1] на голом JavaScript.
Баннер при вызове всплывающего окна:
В качестве backend ASP.NET MVC [2] всё в Azure [3], картинки в Storage, таблички в SQL. Последнее время Редмонд [4] активно рекомендует в качестве frontend шаблон Bootstrap [5]. Собственно, никто и не против, так как по сравнение с тем, что предлагалось раньше, Bootstrap [5] это просто праздник.
Основная проблема реализации – всплывающее окно из iframe перекрывающее по высоте родителя. На своём сайте можно спокойно вызвать Modal [6] через parent iframe’а, но в данном случает домен у iframe другой и браузер будет защищаться. То есть CORS [7]. Партнёры весело и дружно правящие конфигурации на своих веб серверах постановкой задачи не предполагаются.
Если нельзя трогать партнёрские сайты, то можно трогать наш iframe.
Костыль: в фоне под открывшимся Modal окошком увечить высоту iframe так, чтобы Modal помещался целиком или почти целиком.
На HTML5 API window.postMessage [8]. Есть несколько библиотек [9] на 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 [10]
HTML на стороне партнёров
<iframe id="myIframe" src="http://bootply.com/render/112265" width="100%" scrolling="no"></iframe>
JavaScript на стороне партнёров вот тут товарищ сделал компактно [11]
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 [12]
На Jsfiddle подгружается iframe из Bootply, но Bootply заворачивает в ещё один iframe, который надо убрать (см. рисунок).
Неплохо также добавить общий resize:
$(window).resize(function () {
//но с проверкой на открытый Modal
if ($('#myModal').hasClass('in') == false)
parent.postMessage($("#mainContent").height() + 1, "*");
});
Автор: CrackedSapphire
Источник [13]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/54844
Ссылки в тексте:
[1] iframe с минимальной функцией resize: http://stackoverflow.com/questions/9975810/make-iframe-automatically-adjust-height-according-to-the-contents-without-using?lq=1
[2] ASP.NET MVC: http://www.asp.net/mvc
[3] Azure: http://www.windowsazure.com/
[4] Редмонд: http://www.microsoft.com/
[5] Bootstrap: http://getbootstrap.com/
[6] Modal: http://getbootstrap.com/javascript/#modals-usage
[7] CORS: http://ru.wikipedia.org/wiki/Cross-origin_resource_sharing
[8] HTML5 API window.postMessage: http://javascript.info/tutorial/cross-window-messaging-with-postmessage
[9] библиотек: https://github.com/davidjbradshaw/iframe-resizer
[10] Полный код для iframe на Bootply: http://bootply.com/112265#
[11] тут товарищ сделал компактно: http://davidwalsh.name/window-iframe
[12] Полный код на стороне партнёров на Jsfiddle: http://jsfiddle.net/Vitaliy_Kotov/u2MGv/
[13] Источник: http://habrahabr.ru/post/212347/
Нажмите здесь для печати.