Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Positioning dialog elements inside iframe #260

Closed
pomartel opened this issue Sep 27, 2015 · 7 comments
Closed

Positioning dialog elements inside iframe #260

pomartel opened this issue Sep 27, 2015 · 7 comments

Comments

@pomartel
Copy link
Contributor

Working with libraries such as Jquery UI Dialogs or SweetAlert, centering dialogs inside the iframe is a big issue since absolute positioning does not work.

@davidjbradshaw You mentioned that to work around this issue you need to write a bunch of JS and this is pretty much true in my experience. #83 (comment)

Facebook helps you deal with these issues with a positioning API you can call to get the scroll position inside the iframe relative to the parent when building canvas apps (apps living inside an iframe on facebook.com). https://developers.facebook.com/docs/reference/javascript/FB.Canvas.getPageInfo

I was wondering if a positioning API would be feasible for iframe-resizer. If I can get the offset from the the parent frame and the height of the child iframe, then it should be pretty straightforward to position things in the iframe.

Thanks for your consideration and great work on iframe-resizer.

@davidjbradshaw
Copy link
Owner

Interesting idea, should be pretty simple to implement the same API. I'll have a look next time I have some free time, or happy to take a pull request if you want to do it.

@davidjbradshaw
Copy link
Owner

That said I still think your better off having SweetAlert in the parentPage and then sending the content to it via parentIFrame.sendMessage(). This is simpler now than when I wrote the comment in #83.

@pomartel
Copy link
Contributor Author

Thanks for the quick answer David. I am using iframe-resizer so that anybody can add an iframe widget to their website. I don't own the parent iframe (other than asking users to add a snippet of code to their page). Otherwise your solution would have worked. I will check if it would be complicated for me to submit a pull request. I'm not such a great JS developer so we'll see!

@pomartel
Copy link
Contributor Author

Well it looks like @joschi127 might have solved the problem already! https://github.com/joschi127/iframe-scroll-position

I will take a look at it tomorrow and close the ticket if it does the job.

@davidjbradshaw
Copy link
Owner

Interesting, not seen that before. It was written for v2. Simpler to do that in v3, as it includes posting messages from the parent to the iFrame. It could also be simplified by using initCallback, instead of the jQuery search on the iFrame.

I'm thinking the best solution would be to have a method on the parentIFrame object that when you give it a callback function, it tells the parent page to start sending position info until you tell it to stop.

@hedleysmith
Copy link

hedleysmith commented May 9, 2017

Anyone interested in implementing something like iframe-scroll-position but without the jQuery dependency, here's what I came up with:

In the parent window:

ready(function () {
  var iframe = document.getElementById("partialDashboard");
      var sendScrollPosition = function () {
          var data = {
            top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0,
            iframeTop: iframe.offsetTop,
          };
          iframe.contentWindow.postMessage("parentScrollPosition:" + JSON.stringify(data), "*");
      };
      iframe.addEventListener('load', sendScrollPosition);
      window.addEventListener('scroll', function() {
        sendScrollPosition();
      });
});

In the iFrame

if (window.parent) {
  window.addEventListener('message', (e) => {
    if (e.data && typeof e.data === 'string' && e.data.indexOf('parentScrollPosition:') === 0) {
      const dataString = e.data.substr((String('parentScrollPosition:')).length);
      const data = JSON.parse(dataString);
      if (data) {
        window.topOffset = data.top - data.iframeTop;
      }
    }
  }, false);
}

I'm using this in a React.js app loaded in an iFrame. I'm using it to calculate the offset for a modal launched using react-portal. Hacky but it works fine for me for the moment.

Probably worth adding a debounce function around the scroll event and as davidjbradshaw said it would be better to build something where code from within an iFrame 'requested' the current scroll position rather than sending a message constantly.

@ZowWeb
Copy link

ZowWeb commented Nov 17, 2022

I had a modal opening inside the child. Since the iframe takes up the entire size, the modal didn't show in the center of the parent viewport. So I came up with this solution.

if ('parentIFrame' in window) {
  const modalScrollYPos = modalRef.current.getBoundingClientRect().top
  window.parentIFrame.scrollTo(0, modalScrollYPos)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants