2

Hope my Question is enough clear. I own a website. http://khchan.byethost18.com My problem is in the tab "Calendar", it run properly in chrome, ie. but not in fixfox.

my design is that when I hover the calendar tab. the page of calendar will show. but in firefox, when I do that, it don't show properly. developer tool show $bookblock.bookblock is not a function. If I reload the frame, such error message will not show.

If I directly load "http://khchan.byethost18.com/cal.php It can show properly and such error message don't appear.

so I guess may be something is not load properly. I already try add $(top.document,document).ready({function(){}); or replace the jquery library to the head or body. the problem still exist.

since the coding is very long. I only write the iframe tag.Please try to use developer tool to view my code.

I tried document.getElementById('CalF').contentWindow.location.reload(); if I already hover the calendar tab, the tab can be reload properly. but if not, the developer tool display the same error message.

so, I think the major key to the problem is that the jquery tab affect something so that the tab "CalF" can't work properly.

.boxoff{
  display: none;
  }
<article class='boxoff'> //this article will be hidden until I delete the class.
<iframe id=CalF src="cal.php" style="top: 0;"></iframe>
</article>

Thanks.

Kenneth Chan
  • 460
  • 3
  • 15
  • Do you get any errors logged such as something like `mixed content`? – zer00ne Jan 09 '16 at 08:25
  • The firefox only have these error/warning message. Using //@ to indicate sourceMappingURL pragmas is deprecated. Use //# instead jquery.min.js:1:0 TypeError: getComputedStyle(...) is null // this and next error will be solved if I go to the calendar tab and reload the iframe. TypeError: config.$bookBlock.bookblock is not a function – Kenneth Chan Jan 09 '16 at 09:07
  • Hi All, now I use the below method to solve but I think it is not a good method. when the active tab is changed, I check if the browser is fixfox and the active tab is calendar. If both are yes, I will reload the iframe. – Kenneth Chan Jan 09 '16 at 10:00
  • One of the biggest problems (besides the security restrictions), is that it takes longer for iframes to load than any other element usually. If the iframe has a load heavy site, you'll need more time for it to actually load. I'll post a solution that might help. Gimme a minute. – zer00ne Jan 09 '16 at 15:19

2 Answers2

2

iframeLoaded()

Update 2

OP explained that the iframe must be invisible initially. While this may seem an impossibility since iframes do not load when it or one of it's ancestor elements are display: none;. The key word is invisible which is a state in which the iframe is not visible.... There are three CSS properties that come to mind and one of them is actually shouldn't be used in this situation.

  • display: none; This is the property being used by OP and this property actually hinders the iframe's loading. The reason why is when in that state of invisibility, the iframe is not in the DOM according to Firefox's behavior.

  • opacity: 0; This property renders the iframe invisible as well and Firefox seems to recognize the invisible iframe just fine.

  • visibility: hidden; This seems to be an acceptable as well....

So try this code that I use to suppress the FOUC:

Child Page

function init(sec) {
    var ms = parseFloat(sec * 1000);
    setTimeout('initFadeIn()', ms);
}

function initFadeIn() {
    $("body").css("visibility","visible");
    $("body").fadeIn(500);
 }

HTML

<body style="visibility: hidden;" onload="init(2);">

Update 1

  • I made an alternative solution because I hate leaving a demo that doesn't completely work★.

  • Ok this relies on cal.php window.onload event which is basically the slowest but the most stablest phase of loading there is.

  • Initially, #overlay will block any user interaction while calF is loading.
  • Once calF is completely loaded, it will call iframeLoaded function that's located on the parent page.
  • iframeLoaded will remove #overlay (I added a setTimeout for good measure but it's probably not necessary.)

I'm not that familiar with PHP syntax, so you'll have to modify the following code✶ and place it in cal.php

window.onload = function() {
    parent.iframeLoaded();
}

Then on the parent page:

function iframeLoaded() {
   setTimeout(function() { 
      $('#overlay').hide(750);
   }, 1500);
}

The code above as well as the required HTML and CSS is in the snippet below.

Note: The code in the snippet should work, but this snippet won't of course because there's some code that needs to be on the child page. That's just a shoutout to all the downvoters out there ;-)

Snippet 1

// iframeLoaded will remove the overlay when cal.php has completely loaded 

function iframeLoaded() {
  setTimeout(function() {
    $('#overlay').hide(750);
  }, 1500); //<========[1 to 2 (1000 - 2000ms) seconds should give you plenty of time]
}


/*~~~~~~~~~~~~~~~~~~~~~~~~[Code in cal.php]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

// When everything (DOM, script, images. etc...) is loaded on cal.php, call iframeLoaded function that is on the parent's page.

window.onload = function() {
  parent.iframeLoaded();
}
#overlay {
  background: rgba(0, 0, 0, .3);
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}
#CalF {
  position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="overlay"></div>

<iframe id="CalF" src="http://khchan.byethost18.com/cal.php" height="100%" width="100%" frameborder="0" style="top: 0;"></iframe>

✶ Function loadedIframe() inspired by SO5788723

Snippet 2

document.getElementById('CalF').onload = function(e) {
  var over = document.getElementById('overlay');
  over.classList.add('hide');
}
#overlay {
  background: rgba(0, 0, 0, .3);
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}
.hide {
  display: none;
}
#CalF {
  position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="overlay"></div>

<iframe id="CalF" src="http://khchan.byethost18.com/cal.php" height="100%" width="100%" frameborder="0" style="top: 0;"></iframe>
Community
  • 1
  • 1
zer00ne
  • 31,838
  • 5
  • 32
  • 53
  • Thanks for your effort. It may be ok if a general case. but it won't run for my website. In firefox, the console will show parent.iframeLoaded() is not a function. I already try to paste the code in the header of html or inside document.ready. The problem may be due to Jquery tab addin. The iframe"CalF" is in the article. this article is "display: hidden" at the beginning. so the php code of inside the article may not be loaded. include div "#overlay". – Kenneth Chan Jan 10 '16 at 05:54
  • You need to make article either opacity: 0; or visibility: visible; if any ancestor element of the iframe is display: none, then the iframe will not begin to load until it's in the DOM. diplay: none; puts elements into a limbo and treated as if they don't exist at all. – zer00ne Jan 10 '16 at 10:25
  • Thanks. If so, I must give up using iframe since I want the page to be invisible at the beginning. – Kenneth Chan Jan 10 '16 at 14:48
  • @KennethChan I have one more thing for you to try, I'll update my post ;-) Btw, thanks for accepting my answer. :-) – zer00ne Jan 10 '16 at 17:55
  • I like your layout, too bad. Since your pages are on the same domain, you could use AJAX. – zer00ne Jan 15 '16 at 09:24
  • Thanks. but it seem I need to change many thing. since opacity: 0 still hold the space for element but display: none is not. To me, little change will lead to be "many thing need to be write again." For example, I don't add a property that "html" is height: 100%. but after I do some minor adjustment. this property will exist even I can't find where I wrote. and my main page exist a scroll bar then even the space is enough to display. – Kenneth Chan Jan 15 '16 at 09:25
  • Thank your for your admiration. For your idea of AJAX, If I use something like that is better instead? `
    ` .It seem more simple.
    – Kenneth Chan Jan 15 '16 at 09:32
  • I'm not good with PHP, I'm just front-end, but it looks to me that that would function the same as AJAX I suppose. It's an `include`, right? – zer00ne Jan 15 '16 at 09:35
  • yes. `include` is also ok. `require` will display error if the page can't be loaded. – Kenneth Chan Jan 15 '16 at 09:37
  • Yeah I think that's your best choice, my site runs hundreds of iframes within modals and the content is delivered by AJAX and the interactive content like quizzes are delivered by PHP. – zer00ne Jan 15 '16 at 09:40
0

$(document).ready seems to be called too soon, based on parent page instead of iframe content.

here you have solution to a similar problem: jQuery .ready in a dynamically inserted iframe

Community
  • 1
  • 1
sbsbessa
  • 51
  • 4
  • Thanks. I saw the link. but I think the problem is not related to too soon called. I edited my new discovery to the post. It seem if the parent of the iframe (article)is not visible, the coding in the iframe can't be load properly. – Kenneth Chan Jan 09 '16 at 07:54