Bootstrap modal at top of iframe regardless of scroll position. How do I position it on screen?

为君一笑 提交于 2019-12-04 22:53:51

If your iframe has the same document.domain as the parent window or it is a sub domain, you can use the code below inside the 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 will fire after you call $('#myModal').show() window.top.scrollY will get the scrollY position from the parent window

In case your document.domain differs from the parent, you can hack it getting the onmousedown position inside the iframe. For example:

$('#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);
});

Quite old question but I don't see the solution/workaround I've found. It might be helpful for someone in the future.

I had the same issue - my iFrame doesn't fill the entire screen, it displays bootstrap's modal and it is loading content from different domain than the parent page.

TL;DR

  1. Use window.postMessage() API - Documentation here. for communication between parent and iframe (cross-domain)
  2. pass message with currentScrollPosition and Y position of your iframe
  3. Reveive message and update modal's padding from the top

In my case the workaround was to use window.postMessage() API - Documentation here. It requires to add some extra code to the parent and handle message in an iFrame.

You can add EventListener and listen to 'scroll' event. Each time the event handling function is invoked you can get currentScrollPosition like document.scrollingElement.scrollTop. Keep in mind that your iframe can have some margin from the top in the parent page so you should also get its 'offset'. After that you can post these two values to your iframe e.g. ncp_iframe.contentWindow.postMessage(message, '*');

Note that the message has to be a String value

After that in your iFrame you need to add EventListener and listen to 'message' event. The event handling function will pass your 'message' in event.data property. Having that you can update modal padding. (Looks much better if you don't use animations e.g. fade, in classes);

Quick Example:

Parent:

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, '*');
});

iFrame:

window.addEventListener('message', function(event) {
  var messageContent = event.data.split(':');
  var topOffset = messageContent[0];
  var currentScroll = messageContent[1];

  //calculate padding value and update the modal top-padding

}, false);
KyleMit

This is a bug in most browsers (IE appears fine) where the elements are fixed to the iframe, not the window. Typically, if you need something to be relative to the main document, it has to be in the main document.

A workaround is to wrap your iframe in a fixed position div that takes up the whole width of the screen and then maximize the iframe within that. This appears to resolve the issue

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%;  
} 

Working Demo in fiddle

See Also:

It is because the class .modal has position: fixed attribute. Try position: relative instead.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!