Make all JS wait for page load - javascript

I have alot of javascript on a page, It can't be combined.
It's bugging me with the amount of "document.wait" and so forth functions on each of them, is there a better way of doing this, or am I stuck with it?
Goog'ling has revealed nothing.

As said by others move all your scripts to the bottom of the page, right before </body>. It will solve many of your issues. But it will not tackle all the subtleties of browser-inconsistencies specially for old IE.
If you want to get a glimpse of how tricky is to provide such cross-browser implementation, take a look at the following popular question:
$(document).ready equivalent without jQuery
For instance do not lean against document.addEventListener as IE proposes its own proprietary document.attachEvent. And this is only the very first step.

The best practice is to always put script tags just before you close the body:
<script src="path/to/my/script"></script>
<!-- more scripts, etc -->
</body>
This way, everything else is definitely already loaded and no need to "wait".
See this recommendation from google.
Otherwise, you can use:
window.addEventListener('load', function() {
//your js here
});

Related

jQuery breaks all other scripts despite "(function($) { })(jQuery);" wrap

I've been working on a photography portfolio page and want to use different jQuery slideshows for each photo group. I realize having lots of different scripts can cause conflicts, but I've made sure that each script is wrapped with (function($) { })(jQuery); to avoid conflicts with the $.
All the scripts played nice together until I added one particular script (jquery.RotateImageMenu.js). It is definitely this script that breaks everything because when I comment it out, everything works fine. Even the other scripts required for that plugin are fine. As soon as I uncomment that script tag, all the jQuery on the page breaks. There are no console errors.
Because there are so many files, I threw it all up on Plunker so the all code is in one place.
I'm aware that none of the images work on Plunker because it was enough of a pain to copy and paste all the script files, let alone go through over 100 image tags and put in direct links.
I am also aware that there may be an easier way to load all these scripts, but at the moment the goal is to get them all to work before figuring out ways to condense. Well, unless combining would eliminate the problem. To be honest, I have no idea if that would work or not or if there's an easier way to go about this. Any suggestions for an easier approach are welcome, even if they aren't necessarily a solution for how I have things set up at the moment.

Javascript like $(document).ready() for "modern HTML5" browsers

This is most likely already a question somewhere, but I cannot find it, as EVERY single search turns up jQuery questions.
I'm looking for a proven method to bind to the document being ready, much like jQuery's $(document).ready(). However, this is for a "modern browser only" page, with very light javascript, and I'd like to avoid loading jQuery here.
Would someone kindly point me in the right direction?
Thanks!
document.addEventListener('DOMContentLoaded', function () {
/* ... */
});
The event "DOMContentLoaded" will be fired when the document has been parsed completely, that is without stylesheets* and additional images. If you need to wait for images and stylesheets, use "load" instead.
* only if the <script> is before the <link rel="stylesheet" ...>
window.onload = function() {} is a standard from the long past ago, whereas it also waits for all the images to load, it is basically a working, functional alternative for some such cases also in all old browsers. A user usually still should wait a second till he makes a responsible action.
Edit: In my case, I needed it for all the libraries being loaded prior to anything else, as they were listed fixed in the footer (jquery). At it is mine dependency to continue to work with is possible just once it is loaded. So IMHO the fact that the user has to wait is irrelevant (unless I miss something here and am available to be explained), as it's the case with any way of jQuery loading, till it's not loaded it can't be worked with it. For the sake of that point ofc any way there must be a backend check as client-side js can be "intercepted". Waiting for an entire document to load is certainly more lengthy than using it just after its inclusion, however this is for cases when you eg. can't affect the order of html scripts, eg when you use it in own 3rd party package.

Combining Multiple jQuery Scripts

I'm trying to create a simple portfolio site for a friend of mine based around his drawings and paintings. The layout is relatively simple but is proving to be very difficult to implement. I have three jquery scripts on the page that each perform a specific function.
1) bgStretcher - Stretches a series of background images to fill a user's window.
2) collapse - Simple collapsable menu system
3) galleryview - Basic no frills slideshow gallery
Currently, bgstretcher and collapse are on one page called nav.shtml (http://yungchoi.com/nav.shtml) and the gallery on gallery.shtml(http://yungchoi.com/gallery.shtml). Seperatley they work fine, but when I call the nav page via SSI (test.shtml), The code seems to run into problems and becomes disabled.
The solutions I've found all lead to utilizing the noConflict function in jquery (http://stackoverflow.com/questions/2656360/use-multiple-jquery-and-jquery-ui-libraries), (http://hubpages.com/hub/How-to-use-jQuery_noConflict), but everytime I've tried inserting it and changing my code, everything gets messed up again. I've also organized each script's files into separate folders and directories but that hasn't helped either.
My experience is in graphic and web design, so my coding skills are not the greatest. I do know the basics, but rewriting jquery code was not something I ever learned so I might not be understanding how to correctly fix this problem. If someone could clearly and easily explain what I would need to do to make these all work together, I'd appreciate it greatly.
Thanks!
You still have multiple versions of jQuery being loaded in your page.
Remove:
<script type="text/javascript" src="support/bgstrecher/jquery-1.3.2.min.js"></script>
and
<script src="support/collapse/jquery-1.2.1.min.js" type="text/javascript"></script>
you should also remove:
<script type="text/javascript">
$.noConflict();
// Code that uses other library's $ can follow here.
</script>
& - (because you only need either the packed or unpacked version, not both)
<script type="text/javascript" src="galleryview/jquery.galleryview-2.1.1.js"></script>
See if that helps.
You only need noConflict if you're going to also use other libraries that are similar to jQuery like MooTools, Dojo or Prototype. It's unlikely you will need to & if you do, you will need to recode to use the jQuery function instead of the $.
The issue it appears you're having is that all these jQuery includes are overwriting the previous version of jQuery which the plugin attached to and thus the function no longer exists when you call it.
Why are you loading Jquery twice ?
First the 1.4.2 min file and then the full blown straight after ?
You still have multiple calls to jQuery (even if files are not in same directories).
In the same way, you call "galleryview/jquery.galleryview-2.1.1.js" twice (the second file is just packed).
By the way, my error console tell me that:
"Error: jQuery.timer is undefined
Source File: http://yungchoi.com/galleryview/jquery.timers-1.2.js
Line: 135"
Are you sure you need this timer plugin? For now, it seems you have too many script included. Try to remove all unneeded files (you should keep only one version of jquery. But if some plugins you used is not compatible with, you'll have more and more compatibility problems).

Custom View Engine to solve the Javascript/PartialView Issue?

I have seen many questions raised around PartialViews and Javascript: the problem is a PartialView that requires Javascript, e.g. a view that renders a jqGrid:
The partial View needs a <div id="myGrid"></div>
and then some script:
<script>
$(document).ready(function(){
$('#myGrid').jqGrid( { // config params go here
});
}
</script>
The issue is how to include the PartialView without littering the page with inline tags and multiple $(document).ready tags.
We would also like to club the results from multiple RenderPartial calls into a single document.Ready() call.
And lastly we have the issue of the Javascript library files such as JQuery and JQGrid.js which should ideally be included at the bottom of the page (right before the $.ready block) and ideally only included when the appropriate PartialViews are used on the page.
In scouring the WWW it does not appear that anyone has solved this issue. A potential way might be to implement a custom View Engine. I was wondering if anyone had any alternative suggestions I may have missed?
This is a good question and it is something my team struggled with when JQuery was first released. One colleague wrote a page base class that combined all of the document ready calls into one, but it was a complete waste of time and our client's money.
There is no need to combine the $(document).ready() calls into one as they will all be called, one after the other in the order that they appear on the page. this is due to the multi-cast delegate nature of the method and it won't have a significant affect on performance. You might find your page slightly more maintainable, but maintainability is seldom an issue with jQuery as it has such concise syntax.
Could you expand on the reasons for wanting to combine them? I find a lot of developers are perfectionists and want their markup to be absolutely perfect. Rather, I find that when it is good enough for the client, when it performs adequately and displays properly, then my time is better spent delivering the next requirement. I have wasted a lot of time in the past formatting HTML that no-one will ever look at.
Any script that you want to appear at the bottom of the page should go inside the ClientScriptManager.RegisterStartupScript Method as it renders at the bottom of the page.
http://msdn.microsoft.com/en-us/library/z9h4dk8y.aspx
Edit Just noticed that your question was specific to ASP.NET MVC. My answer is more of an ASP.NET answer but in terms of the rendered html, most of my comments are still relevant. Multiple document.ready functions are not a problem.
The standard jQuery approach is to write a single script that will add behaviour to multiple elements. So, add a class to the divs that you want to contain a grid and call a function on each one:
<script language="text/javascript">
$(document).ready(function(){
$('.myGridClass').each(function(){
$(this).jqGrid( {
// config params can be determined from
//attributes added to the div element
var url = $(this).attr("data-url");
});
});
}
</script>
You only need to add this script once on your page and in your partial views you just have:
<div class="myGridClass" data-url="http://whatever-url-to-be-used"></div>
Notice the data-url attribute. This is HTML5 syntax, which will fail HTML 4 validation. It will still work in HTML 4 browsers. It only matters if you have to run your pages through html validators. And I can see you already know about HTML5
Not pretty but as regards your last point can you not send the appropriate tags as a ViewData dictionary in the action that returns the partial?

Initiate onclick faster than with document.onload

I have html-pages with links where i want to attach a function to their onclick event. One way to do it is of course:
Save
But I know this is not the best practice. So instead I wait for window.onload, loop through the links and attach the save-function to the links with rel="save". The problem with this is that it waits until the whole page has finished loading which can be several seconds after the link is displayed and clickable.
So is there another way to do this? Avoiding onclick in the html but that makes it work immediately when the link is rendered.
Internet Explorer has a handy attribute for <script> tags called defer. It's for delaying the parsing of a script until the document has finished loading. For other browsers that support it, you can use DOMContentLoaded, as someone else suggested and for browsers that don't support either you can fall back to onload.
<script type="text/javascript" defer>
//- Run this code when the DOM parsing has completed
</script>
I did a quick Google search for "DOMContentLoaded defer" and found the following page that might help:
http://tanny.ica.com/ica/tko/tkoblog.nsf/dx/domcontentloaded-event-for-browsers
In your case, you can just leave that as it is. Stick to the simplest possible thing, even if it is not the general best practice.
You could try DOMContentLoaded event instead of load. IE also gives you the defer attribute for script tags, which defers execution until the DOM is loaded. If those don't work for you, then you are stuck with the solutions you mention, as far as I know.
I don't know if this is appropriate for your solution, but you could insert script immediately below the are with the links you need altered. This script would not be wrapped in a function, allowing the browser to execute it immediately when seen. The effect is that you can run script before the full page is loaded, altering only the items that exist above the script being run. (If you reference something below the script, it will fail.)
BTW, this is almost certainly not a best practice, and some would probably label it a worst practice.
How about this?
Save
Note: This solution requires to users to have Javascript enabled. Not exactly best practice, but may be suitable for your scenario.
The ideal here would be to use the ideas of Unobtrusive Javascript.
In this way, if the Javascript isn't loaded the link would still do something. It's a link right, so it leads the user to another piece of content? - this should work without Javascript. And if the functionality attached to the links can ONLY work with Javascript you should create and insert them into the DOM with Javascript (they aren't clickable if they aren't there...).
(Otherwise how about delegating the click event to a wrapper element? Does that work before the element is complete?)
edit: Oh, and "save" sounds very much like it ought to be a button in a form rather than a link. The Unobtrusive JS stuff still applies though.

Categories

Resources