Bootstrap modal в верхней части iframe независимо от положения прокрутки. Как разместить его на экране?
При встраивании приложения Bootstrap в iframe модальные диалоги всегда открываются в верхней части iframe, а не в верхней части экрана. В качестве примера перейдите в http://getbootstrap.com/javascript/ и откройте пример модальной страницы. Затем, используя пример кода ниже, который помещает одну и ту же загрузочную страницу в iframe, найдите модальный файл и откройте его:
<html>
<head>
</head>
<body>
<table width="100%">
<tr><td colspan="2" style="height:80px;background-color:red;vertical-align:top">Here some header content I don't control</td></tr>
<tr><td style="width:230px;height:10080px;background-color:red;vertical-align:top">Here some sidebar content I don't control either</td>
<td valign="top">
<iframe width="100%" height="10000px"
scrolling="no" src="http://getbootstrap.com/javascript/">
</iframe>
</td>
</tr>
</table>
</body>
</html>
Демо в скрипке
Как мне разместить позиционирование модала на экране в этом сценарии?
ОБНОВЛЕНИЕ: К сожалению, мой iFrame не может заполнить экран, и я не могу его устранить, так как он должен вписаться в остальную часть страницы, а сама страница имеет достаточно содержимого для прокрутки. Это не мой дизайн, и я в конечном итоге намерен переработать все это, но сейчас это то, над чем я должен работать. В качестве временного варианта я использую javascript, чтобы сообщить родителям iframe прокручивать вверх, где появляется модальное диалоговое окно. Хотя это приемлемо, это не является желаемым поведением.
Я использую angularjs и библиотеку ui-bootstrap в своем коде, но, как вы можете видеть выше, это проблема с загрузкой.
Ответы
Ответ 1
Если ваш iframe имеет тот же document.domain, что и родительское окно, или это поддомен, вы можете использовать приведенный ниже код внутри iframe:
$('#myModal').on('show.bs.modal', function (e) {
if (window.top.document.querySelector('iframe')) {
$('#myModal').css('top', window.top.scrollY); //set modal position
}
});
show.bs.modal сработает после того, как вы вызовете $ ('# myModal'). show()
window.top.scrollY получит позицию scrollY из родительского окна
В случае, если ваш document.domain отличается от родительского, вы можете взломать его, получив позицию onmousedown внутри iframe. Например:
$('#htmlElement').on('mousedown', function (event) {
event.preventDefault();
$('#myModal').data('y', event.pageY); // store the mouseY position
$('#myModal').modal('show');
});
$('#myModal').on('show.bs.modal', function (e) {
var y = $('#myModal').data('y'); // gets the mouseY position
$('#myModal').css('top', y);
});
Ответ 2
Довольно старый вопрос, но я не вижу найденного решения/обходного пути. Это может быть полезно для кого-то в будущем.
У меня была та же проблема - мой iFrame не заполняет весь экран, он отображает модальный загрузчик и загружает контент из домена, отличного от родительской страницы.
TL; DR
- Используйте API
window.postMessage()
- Документация здесь. для связи между родителем и iframe (междоменный)
- передать сообщение с currentScrollPosition и позицией Y вашего фрейма
- Получать сообщения и обновлять модальные отступы сверху
В моем случае обходным решением было использование API window.postMessage()
- Документация здесь.
Требуется добавить некоторый дополнительный код к родителю и обработать сообщение в iFrame.
Вы можете добавить EventListener и прослушать событие "прокрутка". Каждый раз, когда вызывается функция обработки события, вы можете получить currentScrollPosition, как document.scrollingElement.scrollTop
.
Имейте в виду, что ваш iframe может иметь некоторый запас сверху на родительской странице, поэтому вы также должны получить его 'offset'.
После этого вы можете опубликовать эти два значения в своем iframe, например ncp_iframe.contentWindow.postMessage(message, '*');
Обратите внимание, что message
должен быть строковым значением
После этого в вашем iFrame вам нужно добавить EventListener и прослушать событие message.
Функция обработки событий передаст ваше "сообщение" в свойство event.data
. Имея это, вы можете обновить модальные отступы. (Выглядит намного лучше, если вы не используете анимацию, например, fade, в классах);
Быстрый пример:
Родитель:
window.addEventListener('scroll', function(event){
var myIframe = document.querySelector('#myIframe');
var topOffset = myIframe.getBoundingClientRect().top + window.scrollY;
var currentScroll = document.scrollingElement.scrollTop;
myIframe.contentWindow.postMessage(topOffset + ':' + currentScroll, '*');
});
Ответ 3
Это ошибка в большинстве браузеров (IE выглядит отлично), где элементы привязаны к iframe
, а не к окну. Как правило, если вам нужно что-то относительно основного документа, оно должно быть в основном документе.
Обходной путь заключается в том, чтобы обернуть ваш iframe в фиксированную позицию div, которая занимает всю ширину экрана, а затем максимизирует iframe внутри этого. Похоже, что проблема устранена.
HTML
<div class="fixframe">
<iframe src="http://getbootstrap.com/javascript/"></iframe>
</div>
CSS
.fixframe {
position: fixed;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
}
.fixframe iframe {
height: 100%;
width: 100%;
}
См. также:
Ответ 4
Это потому, что класс .modal
имеет атрибут position: fixed
. Вместо этого попробуйте position: relative
.