I'm using a src less iframe to develop a javascript widget to protect my css from the parent page.
It's perfectly working in chrome/safari. However in firefox I can see the content is added during few milliseconds and then the iframe becomes empty.
If I inspect html I see empty head and empty body, however if I inspect innerHtml through the console I can see that It has the right content...
I'm sorry I can't give you code as it's hard to pull out the relevant parts : I can tell you I access the iframe with jquery contents() and then find body or find head.
Any idea plz ?
I Managed to make an example : http://jsbin.com/arenat/2/edit#javascript,html,live
Just some code pull out to show the issue : working on chrome no in firefox (10.0.1). Hope it's enough.
When you add the frame to the DOM, it starts loading about:blank asynchronously. Then you modify the DOM in the iframe ... and then the asynchronous load completes and replaces the document you modified.
I suggest either using an onload handler on the iframe to do your manipulation after the about:blank has finished loading or using document.open() and document.close() to force cancellation of the async load.
It's working with a timeout :
http://jsbin.com/arenat/9/edit
Related
While debugging, I see the message "Layout was forced before the page was fully loaded. If stylesheets are not yet loaded this may cause a flash of unstyled content." When I get this message, Firefox does not find my functions in
<script src='Game_Help.js' onload="alert('loaded')"></script>
If I remove <script>, the message goes away, but of course those functions are still not being found.
The strange thing is, I have a similar problem with Edge. Chrome works fine.
PS: I used the onload function to see if script was being loaded.
I can make a workaround using an iframe, but that seems strange.
So what is happening is that the alert itself is interrupting the loading of content, causing the warning. So to fix it (and keep the script in the head section), remove the onLoad event from your script tag, and add an event listener containing the alert to your external javascript file:
document.addEventListener("DOMContentLoaded", function(){ alert('loaded') });
This listener will wait until other content is loaded before it will run.
The other way to fix this is to move the script tag to the body (HTML loads top to bottom, so you are just letting everything else load up more or less until it gets to the script). If your content is fairly complex or there are multiple scripts using the event listener will be a more robust and specific solution.
I am trying to read this HTML in the console in Chrome:
<span id="lblSummaryFreight">Kr 79</span>
Using this JS:
document.getElementById('lblSummaryFreight').innerHTML;
However, after the page has loaded, running this line returns null or invalid. If i inspect the element and then run the code, it works as intended and returns "Kr 79". So, is it some kind of DOM issue I am not aware of, or a browser-specific issue?
I am using this as a variable in Google Tag Manager, and it works in 50% of the cases. I don't have access to the source code of the webpage itself, so that's why I need to lean on this rather clunky way of getting the data.
A lot of posts on this suggest that this is because the script is fired before the DOM is ready, but I don't think this is an issue, as I am also testing this in the console after the page has loaded (and the HTML elements are present), and in Google Tag Manager I have specified that the tag should fire after DOM is ready.
Any clues?
Edit / Clarification: I can't alter the code of the page itself, only read the output source, which i am trying with JS via GTM
Don't seem to be able to resolve this issue, and as it seems to be the fault of some quirky source, I will try to figure out another way to get the data I need.
What I have learned:
The issue seems to be specific to Chrome, as it works in other browsers. This is supported by the fact that the GTM tag where this code is implemented returns correct values in ~50% of the cases
Testing the page in Android native browser, it will also return 'undefined'. After reloading the page that fires the tag, it returns correct value.
The whole DOM seems unavailable in the console. Tried also this:
document.getElementsByClassName('complete').length
Which returns 0, but there are around 10 instances of the class in the source. After inspecting anywhere on the page, it returns correct number.
Any delay in running the script won't help, only the symbolic inspecting of elements or reloading the page helps.
So my conclusion is that the way this webpage is built somehow goes against the grain of some browsers - it seems like the source goes out of the memory after the source is loaded. But this is way beyond my level of understanding.
Thanks all for all inputs!
It looks like an async issue. Try this:
//Using Jquery
$( document ).ready(function() {
document.getElementById('lblSummaryFreight').innerHTML;
});
or
//Add this at the end of the body, after all of your content
<script>
(function() {
document.getElementById('lblSummaryFreight').innerHTML;
})();
</script>
Try to change how the tag is fired in GTM. Fire them when Window Loaded, and try again.
Maybe the element is being changed in another js file.
Trying jQuery is a good point. I have had similar problems and jQuery have solved them all.
I am currently running the following js on some of my pages to dynamically set the title tag on the page pulling from the h1 tag contained on that page.
document.title = document.getElementsByClassName("Category-H1")[0].innerHTML;
However, when I view the page's source, it still shows the old title tag, even after the js has changed it.
It was suggested to me that I might have to add an "onload event of the body", not sure if this would help, or what onload event I would need to run.
Any other ideas? Suggestions?
Thanks - Alex
The 'source' is just that ... it is the code returned from the server. In most cases to see DOM changes made after loading you will need to look at the code in Firebug or Chrome Inspector.
Hopefully someone here can help me with this challenge!
I have a parent page which is the checkout page for an e-commerce site. It's run on zencart and for every order placed a table row is generated through ZenCart. I've setup an EACH function which generates an iframe for an artwork uploader for each TR (order) found. The uploader works and the correct number of instances are being generated.
I wanted to avoid an iFrame, but the uploader script I purchased will not permit me to load it directly into the zencart page template, or via AJAX (tried both). There's some kind of major resource/path situation going on when doing it this way... so I've resorted to iframes.
I'm able to call JS on file-upload-complete. At that point I'm trying to capture the name of the filename that was just uploaded and place it inside the TR. The problem I'm running into are permission error when trying to access the iframe contents.
I've tried everything I've come across on this site and many others, so believe it isn't a problem with the selectors/frame selection... Firebug is telling me that I'm getting permission errors when trying to access the iframe, yet they're both on the same domain and the src is being set by a relative path....
I'm completely lost, any suggestions would be appreciated! Thanks!
www.prothings.com/store
Add items to the cart and go to checkout.....
when you want to access main window or window.document from inside an iframe you should change the context by using window.parent
For example when you want to append some text to a div, you should do something like this
window.parent.$.('#theDiv').text('the text');
There is a bug in IE when you run the code from inside the iframe and remove the iframe in between. IE can't run the code in the fly
I can see that this question has been asked several times, but none of the proposed solutions seem to work for the site I am building, so I am reopening the thread. I am attempting to size an iframe based on the height of it's content. Both the page that contains the iframe and it's source page exist on the same domain.
I have tried the proposed solutions in each of the following threads:
Resize iframe height according to content height in it
Resizing an iframe based on content
I believe that the solutions above are not working because of when the reference to body.clientHeight is made, the browser has not actually determined the height of the document.
Here is the code I am using:
var ifmBlue = document.getElementById("ifmBlue");
ifmBlue.onload = resizeIframe;
function resizeIframe()
{
var ifmBlue = document.getElementById("ifmBluePill");
var ifmDiv = ifmBlue.contentDocument.getElementById("main");
var height = ifmDiv.clientHeight;
ifmBlue.style.height = (ifmBlue.contentDocument.body.scrollHeight || ifmBlue.contentDocument.body.offsetHeight || ifmBlue.contentDocument.body.parentNode.clientHeight || height || 500) + 5 + 'px';
}
If I debug the script using fire debug, the client height of the iframe.contentDocument's main div is 0. Additionally, body.offsetHieght, & body.scrollHeight are 0. However, after the script is finished running, if I inspect the DOM of the HTML iframe element (using fire debug) I can see that the body's clientHeight is 456 and the inner div's clientHeight is 742. This leads me to believe that these values are not yet set when iframe.onload is fired. So, per one of the threads above, I moved the code into the body.onload event handler of the iframe's source page. This solution also did not work.
Any help you can provide is much appreciated.
Thanks,
CJ
DynamicDrive has such a script, which I think does what you're asking for.
There's also a newer version now.
2011 update:
I would strongly recommend using AJAX over something like this, especially considering that a dynamically resizing iframe only works across the same domain.
Even so, it's a bit iffy, so if you absolutely must use AJAX over standard page loading, you really, really should use things like history.pushState (and have standard page loading as a fallback for browsers that don't support it). There's a jQuery plugin which handles this stuff for you, written by a GitHubber, called pjax, which they use only for repo navigation.
you moved the handler? maybe you should move the function to the inner frame as well, so that when you grab height values you reference the body directly rather than frame object... then call a parent.set height function
another trick, call function after settimeout of 10 msecs
i remember I had that problem once but I used IE's getBoundingClientRect() to get height of content, check mozilla developer center for something similar, this is just a hint, i did not research it
on another note, what is ifmBluePill? is it the iframe? or a div inside of it? why do you reference "contentDocument" of a div?
By the way, DynamicDrive improved their script to always resize even if the iframe contents change: http://www.dynamicdrive.com/dynamicindex17/iframessi2.htm
From their page:
This is version II of the original
Iframe SSI script, which like the
original script lets you seamlessly
display external content on your page
via an IFRAME. It does this by
dynamically resizing the IFRAME to be
the height of the page contained
within it, eliminating any possible
IFRAME scrollbars from appearing while
snugly showing the entire external
content. Think of it as SSI (server
side includes) emulated using DHTML!
This script works in both IE5+ and
NS6+, and for other browsers, supports
the option to either completely hide
the iframe in question or display it
using its default height.
Now, this script differs from the
original in that you can load
additional documents* into the IFRAME
even after the page has loaded, and
the IFRAME will dynamically adjust its
height to fit the new document. So use
this script if you need to not only
display external content via the
IFRAME tag, but intend to change this
content after the page has loaded.