1

The problem context

I need to resolve the height of the content of an iframe after loading it (in order to adapt the height of the iframe element itself). The problem is that the iframe could be in a hidden state (one of its containers/parents set to display:none), when the loading is done.

I can't find a way to get the correct height of the iframe content as long as I don't display it. Using jQuery.height() returns 0 on Firefox.


An example demo here:

https://codepen.io/anon/pen/gKBQeP?editors=1111

(you'll notice how the height is reported differently in case you immediately click on the Tab3, where the iframe is, making that visible, or if you wait a couple of seconds after loading and then click on the Tab3)


Cannot write height on the element, right after displaying it.

Moreover, after making it visible again I still cannot get the real height of the content; it still returns 0 like it is hidden. I assume because the iframe-content is still in the process of getting rendered, even if the DOM tree of the iframe has been shown already. If I setTimeout few milliseconds after making it visible then I can get the correct height (that doesn't make much sense to me....).

I really don't like to set a timeout in order to read the content height.

What is a reliable, cross-browser, way to get the height of a hidden element, even when this is hidden (or in the process of becoming visible)?

My solution

At the moment I:

  • trigger the read/write of the height right after I know the element is visible again.
  • use setTimeout() to wait half-second (feels sluggish ) before reading/writing the height of the element.

Note (the actual question)

I am trying to find less hacky as possible solutions; so I want to avoid:

  • displaying (or cloning) the element quickly (taking care saving+restoring css properties, making them persistent and inline; or taking care of avoiding flickering in the page), to read the dimensions and quickly set it back to hidden ().
  • using setTimeout to wait the element dimensions being restored (and readable/writeable correctly) in order to work on them immediately after showing the element itself.
Kamafeather
  • 8,663
  • 14
  • 69
  • 99
  • What do you mean by in a 'hidden' state? Just hidden with CSS (display none or visibility hidden)? – cathryngriffiths Jun 27 '18 at 17:02
  • Actually it's hidden with the _checkbox-hack_ (a checkbox determines whether the parent/container of the ```iframe``` is ```display```ed or not). – Kamafeather Jun 27 '18 at 17:46
  • the iframe will get its height from the loaded content. So its 0 before - no matter if you hide it or not. – C4pt4inC4nn4bis Jun 27 '18 at 17:55
  • @C4pt4inC4nn4bis: could be, I don't doubt it. But if you check the link and comment/uncomment the first line you'll see (on Firefox) that the console reports different ```height``` (regardless of the loading state of the ```iframe```). – Kamafeather Jun 27 '18 at 18:05
  • 1
    Do you have control over the content of that iframe? What about measuring in there by using js and then bubbling that info upwards your other window and set the transmitted height? https://caniuse.com/#search=postmessage – C4pt4inC4nn4bis Jun 27 '18 at 18:15
  • Like that https://stackoverflow.com/questions/5606920/cross-domain-iframe-resizer/6940531#6940531 – C4pt4inC4nn4bis Jun 27 '18 at 18:26
  • Yes, that would be the most correct way; I was almost going that direction. But I also wanted to understand the issue here and see if I am missing something about the weird timing that is shown in the example (it feels like the iframe-content rendering is kind of asynchronous and javascript proceeds thinking that the content is still hidden [hence ```height: 0```]). **Edit:** Also, ```postMessage``` is not supported by IE8 and I was trying, for lack of time, to avoid going the direction of integrating libraries like https://github.com/davidjbradshaw/iframe-resizer) – Kamafeather Jun 27 '18 at 18:30
  • Actually I found out that relying on ```postMessage``` doesn't help much, since the limit on hidden elements happens also on **writing** the ```height```, not just on reading it. **The actual issue is in the ```height``` still not (yet) being restored to the content-height, immediately after setting the element to ```display:block``` (few milliseconds that provoke a greatly annoying buggy behaviour).** The demo shows it properly, and my main goal is to understand why this happens and if there are other solutions than using ```setTimeout``` with an empirically-set delay – Kamafeather Jun 28 '18 at 15:57

1 Answers1

1

It's a bit hacky but rather than display:none (I assume that's how it's being hidden) you could set something like:

top: -10000px;
left: -10000px;
position: absolute;

It's "hidden" since it won't be visible, but you will still be able to get its height. Then after you get the height you can remove these styles to make it visible.

emmzee
  • 630
  • 5
  • 14
  • Thank you for the suggestion, but I have no chance to avoid the issue and change the way the elements are hidden. I need to stick to ```display```, and I am actually curious how to resolve the problem, more than how to avoid it – Kamafeather Jun 27 '18 at 18:06