document.addEventListener slows down loading - javascript

I have a Web App. I have written a Calendar javascript code. A script tag is in body of html code loads that js file from server.
Until writing the last codes, loading page was taking around 900 ms. When I wrote last of my javascript codes, it takes 6 seconds loading the page.
Javascript code basically defines a class for my calendar. It has lots of methods in it. In my last codes, I wrote a new method which is like below:
registerHider = function(){
alert('hello');
if(document.addEventListener){
document.addEventListener('click', hider, false);
}
};
The method "hider" is another method which just changes "display" style to "none". That's all. When I comment out "addEventListener" code, page loads around 900ms again. But when I uncomment is it takes 6 secs again.
I put there an alert to see if page tries to process any code there on load, but no message comes to screen. From there I understand, codes are not executed yet. Even I changed code to register the event only if document is ready, no help, still same.
What can be the reason of this problem?

All problems are solved. It has turned out that it wasn't about any of those javascript codes.
Lessons learned: If HTTP header's content-length is higher than content's real size;
Firefox waits longer but it still works.
Chrome fails to load the javascript code. So it doesn't work.
Thanks anyway to everybody attended.

Related

JavaScript Will Not Load After DOM

I'm having trouble getting my JS to run after all my content has loaded. Right now on the site Im working on: http://hsvgridproject.com, the grid will not load the first time a user visit the site and needs a hard refresh before it will work. I believe I need to use a window.onload function of some sort but as I am still learning Java I'm not sure how to implement it into my project without breaking the code.
The script for the grid on homepage has a window tag surrounding it already (credit Codrops):
(function(window) {
Please let me know if you need more info. Thank you!
It's probably not working because you're executing your script before the DOM is fully loaded.
To ensure it's executed after the DOM is fully loaded, either move the script tag which executes your code right before the closing tag of the body element or use DOMContentLoaded event like this:
document.addEventListener("DOMContentLoaded", function(event) {
// execute your code
});

Javascript returns null in Chrome, HTML element in source

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.

Recall external JS files after page transition finish

I have tried to implement this kind of script (Page Transition): here
Everything is going fine as demo provided. But only 1 problem that I cant figure out is:
I have 2 HTML files which is index.html & index2.html. On index.html I put the link with the page transition effect after clicked it goes to index2.html which is on index2.html I was put in some alert script using body on-load method.
Supposedly in normal practice, the alert will appear as normal we seen for debuging. But it doesn't appear anything. Seem like it doesn't load any script after page transition done.
Can somebody give me a clue to solve this? What I have tried is using :
location.reload(); window.location.reload(); etc.. till I don't have idea to fix this :(
*location.reload() works on desktop browser but doesn't work on mobile. My priority target browser is on mobile version.
Please help & Many Thanks
for demo purpose and needs help : here
It wasn't executed because the page never really loaded. The way that page transition script worked is by loading the content of the target page via ajax, replacing the entire content of the page with it.
From the page you provided, it seems like the script accepts a callback function to be called when the page finishes loading, you can put your 'loaded' script there. But keep in mind, what is being executed is the script on that first page.
I don't know what you are trying to make, but I guess it would be better for you to look into a proper single page app with URL matching. There are frameworks like Backbone.js that can help you with this.

unable to refresh a page when i use setInterval() and pass in a function that uses document.write to output some javascript to the page

basically i have a blank html page that includes a javascript file, and in the javascript file i have this:
function doIt() {
document.writeln("asdf");
}
// could also be setTimeout
setInterval("doIt()", 5000);
When the html page loads, it waits 5 seconds and then will output "asdf" every 5 seconds to the screen. If i hit refresh or f5, nothing happens. When i view the source, the page is blank. Is there any reason why when i view source i dont even see the:
<script type="text/javascript" src="test.js"></script>
on the html page? Im assuming i cant refresh the page because of the blank source. Any ways to resolve this?
Thanks!
You cannot use document.write like this after the page finishes loading.
Instead, you should append to the text of a DOM element.
When the html page loads, it waits 5 seconds and then will output "asdf" every 5 seconds to the screen.
When the page has finished loading, the document is closed and can't be written to. So if you call document.write() after this point, it assumes you mean to call document.open() and completely replace the page. The old document is unloaded to be replaced by the new one you're about to write, which is why you can't view the source of the old page any more.
And because you don't call document.close(), the throbber will keep spinning, waiting for the new document to be completed (which will never happen).
As SLaks said, you should interact with the DOM instead of using document.write() which is generally best avoided (except in a few specific cases to do with writing initial documents to popups or iframes).
thanks guys. i was able to see what you guys meant by having to modify the DOM to add in javascript after the page has loaded. I was able to do that but ran into the same issue:
basically i needed to use setInterval to do some polling to wait for data to be sent to this iframe from the parent, once it received the data, then it would output some javascript (which i created a new script element in the DOM for). but the problem is that the src of that element is pointing to an external url from which im getting some data from, and the way that external source returns the data is by using document.write - which i have no control over.
is there any other option for doing the polling besides using setInterval? i'd like to continue polling until a max timeout, and then if the max timeout is reached, then execute the rest of the page, then i wont have to worry about the document.write issue from the external source.
is another option to make that call to the external source and parse the response and create the dom elements with my javascript?
Just an idea, didn't have chance to test it.
Have your script create blank window and inject script into there to call the external script:
var oWindow = window.open("about:blank", "dummy", "width=0,height=0");
oWindow.document.write("<html>");
oWindow.document.write("<body>");
oWindow.document.write("<" + "script" + " type=\"text/javascript\" src=\"external.js\"></" + "script>");
oWindow.document.write("</body>");
oWindow.document.write("</html>");
oWindow.document.close();
and then read the oWindow.document.body.innerHTML to see the "output" of the external script.

dojo.require() prevents Firefox from rendering the page

Im experiencing strange behavior with Firefox and Dojo. I have a html page with these lines in the <head> section:
...
<script type="text/javascript" src="dojo.js" djconfig="parseOnLoad: true, locale: 'de'"></script>
<script type="text/javascript">
dojo.require("dojo.number");
</script>
...
Sometimes the page loads normally. But sometimes it won't. Firefox will fetch the whole html page but not render it. I see only a gray window.
After some experiments I figured out that the rendering problem has something to do with the load time of the html. Firefox starts evaluating the html page while loading it. If the page takes too long to load the above javascript will be executed BEFORE the html finishes loading.
If this happens I'll get the gray window. Advising Firefox to show me the source code of the page will display the correct complete html code. BUT: if I save the page to disk (File->Save Page As...) the html code will be truncated and the above part will look like this:
...
<script type="text/javascript" src="dojo.js" djconfig="parseOnLoad: true, locale: 'de'"></script>
<script type="text/javascript">
dojo.require("dojo.number");
</script></head><body></body></html>
This explains why I get to see a gray area. But why does this code appear there? I assume the require() method of Dojo does something "evil". But I can't figure out what. There is no write.document("</head><body></body></html>"); in the Dojo code. I checked for it.
The problem would be fixed, if I'd place the dojo.require("dojo.number"); statement in the window.load event:
<script type="text/javascript">
window.load=function() {
dojo.require("dojo.number");
}
</script>
But I'm curious why this happens. Is there a Javasctript function which forces Firefox to stop evaluating the page? Does Dojo do somethig "bad"? Can anyone explain this behavior to me?
EDIT: Dojo 1.3.1, no JS errors or warnings.
What does the rest of the page look like? What elements should be rendering that aren't? What other Javascript do you have?
What you have looks fine, but you will not be able to use methods in dojo.number or anything else loaded via dojo.require until after the page loads -- you must wait for window.onload to fire, or use the dojo.addOnLoad() method to trigger a callback. The latter is actually a bit quicker than onload.
dojo.require uses synch xhr to load which does block the browser, so if the load is unusually slow, you will notice a delay in the rendering of the page.
I think this is a rendering bug in Firefox that I've seen in a number of contexts where the one common factor is the amount of time the browser takes to load all the resources loaded in the of the page. The more scripts you have in the head that take a long time to request over the network or eval, the higher your chances are of running into this. Hitting the page with a warm cache notably reduces the possibility of running into the paint bug as well. Another way to mitigate it is to put the javascript at the end of the which is also a best practice since it doesn't block the browser from previewing markup immediately as it gets it.
Regarding the specifics of using dojo, common use cases include running things onload like creating and starting up widgets. If you have code in an onload handler that uses a dojo module like a widget, then stick the dojo.require statement inside the onload handler as well instead of before the onload handler. There's no point in suffering the performance penalty or blocking the initial UI rendering if you don't need it until later. Then build custom dojo layers to include the minimal core (possibly a custom base to make it even smaller) and the other 90% of what you need in a separate layer. Load the minimal core layer in the head (to get dojo.addOnLoad, etc) and then the other layer at the end of the body. If you live in a modular application framework where apps come and go in the page content area depending on the page you're on, each app should put the dojo.require statements for the respective dojo module it uses immediately before the module is actually referenced.
This won't work obviously if you need a module immediately in an inline script, but if that's the case then a custom dojo build will also help mitigate that case also.
I'm unaware of a reported issue with Mozilla, but I have also seen this much less often on other browsers some time ago.

Categories

Resources