Internet explorer window.resize fails after using document.write - javascript

This may be a bug in internet explorer (IE9), wondering if it is known or there is a workaround.
It can be reproduced by opening up the dev console, and executing each of these commands,
window.onresize = function() { alert("onresize"); }
At this point, when you resize the window, the event fires as expected. Now execute,
document.write("test");
After this point window.resize will be null.
That's probably expected since document.write calls document.open which clears everything.
However, even if you add back an event handler, it will never fire,
window.onresize = function() { alert("onresize"); }

You have to write the whole script block into the new document. For example:
document.write("<div>some html</div><script>window.onsize=function() { alert('onresize'); } </script>
This is because when you call document.write it creates a new document with an "empty" url. Where as your original document comes from a different Url (for example, "http://www.yoursite.com/Page1.aspx". The site for the empty Url is not the same as the site of the original Url. And a browser does not allow script in pages from one site calls script in pages from another site (to avoid cross site script attack). Thus it is not possible for you to call a function defined in "http://www.yoursite.com/Page1.aspx" from a page with null Url. As such you have to write the script code itself into the new document.

Related

Does reloading a WebView cancel former calls to setInterval()?

This might be a stupid question, I cannot find the answer though:
I am animating some shapes in a HTML/JS page displayed by an Android WebView. To do so I use the Javascript setInterval() method:
var animateThreadHandler;
function animateThread() {
// animate some stuff here...
}
// This function is called from the HTML page: <body onload="onBodyLoaded()">
function onBodyLoaded() {
animateThreadHandler = setInterval(animateThread, 200);
}
Later, in the code of my Android Activity this time, I switch from this HTML page to another one, keeping the same WebView:
mWebview.loadDataWithBaseURL(baseUrl, htmlContent, HTML_CONTENT_TYPE, HTML_ENCODING, null);
But I never call clearInterval(animateThreadHandler) from the Javascript. Even though this works well, I wouldn't like to drain the user's battery by doing useless Javascript function calls that would end up in errors that I couldn't see.
I monitored the behaviour of the JS animateThread() function by making it to produce logs (see comments), and the logging stops once the WebView is reloaded. But this doesn't prove the scheduler is cleared: calls to animateThread() may keep occurring - and silentely failing as the JS code was unloaded at Webview reload time.
The rationales behind this doubt reside in what the W3School says:
The setInterval() method will continue calling the function until
clearInterval() is called, or the window is closed.
I neither call clearInterval() nor I "close" the window (I'm just reloading it), so I am really not sure of the underlying behaviour of my code. Any idea?

jQuery / JavaScript - Loading iframe with Ajax slows down page

I'm loading a iframe with $.ajax():
$("#iframe_wrapper").each(function(){
$.ajax({
type: "post",
url: "http://site.com",
data: { action: 'get_the_iframe' },
context: this,
success: function(html){
$(this).html(html);
$(this).show();
$('#theiframe').load(function(){
// do stuff with the iframe...
});
}
});
});
the iframe is inside a function that gets called if $_POST['action'] is 'get_the_iframe':
<iframe id="theiframe" name="theiframe" src="http://site.com/page/"></iframe>
it works, but the problem is that the browser seems to display the entire page really slow, it seems like it waits for the iframe to load before displaying the entire content on the page, which is not supposed to happen because it's done trough ajax. This is exactly what I was trying to avoid...
Any ideas what's wrong here?
I think the key to the answer is where, or more specifically, when your jQuery fragment that performs the ajax post is being run by the browser.
I suspect the jQuery code to load the page happens sometime before the full page has loaded. And maybe your browser doesn't support asynchronous loads from the same domain.. This was the case with IE for a long time. So what's going on is the browser starts loading and processing the iframe somewhat in-step with the rest of the requests that your normal (outer) page is doing.
If this is not the case yet try putting the code that starts the ajax post in a document ready handler.
Also, check in other browsers to see if the problem occurs across the board.
The reason why you are seeing this is because IFrame is blocking element, especially in IE. IFrames are the most costly element to create in a browser, and it also will block execution of JavaScript when it's being created. There's also resource blocking rule regarding IFrame as well. If you have CSS files in your page, IFrame will not load until response for each and every CSS file is received by the browser (IE) or in Firefox, all IFrame's resources will be blocked until response is received for all resources on the main page.
Just as an example, I had a standard spinner control, that would display running snake whenever I do AJAX call to the server (to give user some feedback that something is happening). I also was create IFrame element at the body level, to overlay all dropdown elements on the page for IE6/7 bleed through bug. At some point I noticed that my web-service calls where about twice slower in IE then they were in FF. After some investigation, I realized that creation of the IFrame element is blocking everything in the browser, including code that receives response from the server.
I don't think there's a way around it, except for not using IFrames...

How to run JavaScript snippet right before onload event(Google Chrome Extension)

What I'm trying to do is write a Chrome extension that inserts a snippet of Javascript that will fire after all the Javascript code on the page has run, but before the onload event fires. (There is some code on the page that has an event listener for the onload event). I've tried all that I've thought of for my extension, but I haven't found a consistent way to do this with a Google Chrome Extension.
I've tried setting the run_at value to both "document_start" and "document_end", along with appending this snippet to both the head and the body, both as a <script></script> with inner html and a <script></script> with a src pointing to a file in the extension. Nothing consistently works.
Has anybody had any luck with this or any thoughts on how to proceed?
UPDATE!
I've made some progress, but now I've hit another snag. I have the extension set to run_at document_start, and it is always firing before the script is loaded. Then I add an event listener for the event DOMContentLoaded, then send a request to my background page (to get the currently selected options so I know how to modify the script on the page).
The issue now is that sometimes, the event fires before I receive my response from the background page. When I receive my response before DOMContentLoaded, everything works. Since this is asynchronous though, I haven't found a way to somehow force a wait for this response.
Does anybody have any thoughts of how to proceed?
One naive solution would be to put your script just right before you close the body tag. In that way you are sure that all the scripts are loaded and that no onLoad has been called yet
I haven't tried but using the defer attribute should work.
http://dev.w3.org/html5/spec-author-view/scripting-1.html#attr-script-defer
It works in WebKit, but only since last month so it'll take a while until it reaches Chrome stable.
http://webkit.org/blog/1395/running-scripts-in-webkit/
You can try Chrome Canary or a recent Chromium snapshot.
http://tools.google.com/dlpage/chromesxs
http://build.chromium.org/buildbot/snapshots/
It might also require setting a HTML5 doctype.
http://www.w3.org/TR/html5-diff/#doctype

jQuery $(document).ready() failing in IE6 but only after clearing Temporary Internet Files

I'm experiencing problems with $(document).ready not getting executed in IE6, but only after clearing the Temporary Internet Files (so in fact the very first time this page is loaded). On refreshing the page or on later page loads, everything works fine.
This is the current setup:
Portal page with frames, this portal page also has a window.load method (maybe we have a race problem with jQuery ready ??):
window.onload = function () {
try {
expireCookie("COOKIE%2DID");
loadMenu();
} catch (pcbException) {
reportError(pcbException);
}
}
In this portal page, our current page gets loaded. At the bottom of this page we have:
<script language="javascript">
try{
$("#CR").remove();
}
catch(ex){
}
$(document).ready(function() {
alert(typeof $); // check if method is getting executed
RendererPageIsLoading(); // loads data in comboboxes and hides divs
});
</script>
</body>
I'm using the latest version of jQuery (1.4.2).
Edit: jquery is getting loaded in the head section of the current page:
<script language="javascript" type="text/javascript" src="https://fulldomain/js/jquery.js"></script>
Following topic didn't bring any solutions:
jQuery $(document).ready() failing in IE6
Someone suggested (he did remove his answer later on) that attaching a method to the window.onload did detach the method defined in the $(document).ready() event. However since the error only happened the first time the page was loaded, in my opinion this had to be a cache problem.
After further investigation we found out that IE6 was having problems with a transparent png that didn't get loaded correctly. Therefor the browser is waiting for the image to load and IE6 waits on images before it triggers the DOM ready event.
Conclusion: also check for transparent png images if having problems with IE6.
If you are adding a script immediately before the "/body" tag, you don't need to use:
$(document).ready(...);
As the document IS ready (bar from "/body" and "/html").
It is really useful if you have an external JavaScript file that may be loaded faster than the page - in which case it delays the execution until the DOM is ready (or in some browsers the DOM and HTTP requests... which is more like window.onload, which waits for all the images, for example).

Getting JavaScript exception happening in iframe surface

Here is the situation:
A page (iframe.html) has an iframe loading another page (iframe-content.html).
An JavaScript error might happen when iframe-content.html is loaded in the iframe.
I'd like that exception to be visible to the browser (e.g. shown in Firefox error console, or Firebug).
Here is what I see:
When iframe.html is initially loaded, and loads iframe-content.html with src="iframe-content.html", the JavaScript exception shows in Firebug.
However, if the page is loaded in JavaScript (document.getElementById('iframe').src = 'iframe-content.html'), the exception doesn't show.
You can reproduce this by going to:
http://avernet.googlepages.com/iframe.html with Firefox.
You'll see the exception as iframe-content.html is loaded.
Click on the button: the content of the iframe is loaded again, but this time the exception doesn't show in Firebug.
Is there a way at #3 to have the exception show, instead of it being silently ignored? (You can't use a try/catch around the JS code that sets the src, as this code returns immediately before the page is loaded in the iframe.)
It seems that your iframe page is not really loaded on the second time. Or it's loaded from the cache and the error is ignored. This is interesting, but I think I found an way around it.
function setContent() {
try {
console.log("Loading iframe content");
document.getElementById('iframe').src = 'iframe-content.html?foo=bar';
} catch (e) {
console.log("Caught", e);
}
console.log("Done loading");
}
With that the error should appear.
What I did, was to trick the browser to think that I'm loading a brand new page as the parameters after the url have changed.
'iframe-content.html?foo=bar';
You could replace my "bar" string with a changing timestamp. Sure, it would avoid the cache, but it would also force it to generate the error like you wished.

Categories