How to run a jQuery function after all and any other javascript has run
Asked Answered
D

2

7

I have a photo gallery page hosted on a CMS (Squarespace) which has some of it's own scripts which load the thumbnails asynchronously.

The actual large images however are not preloaded, so I decided to add my own script into the mix to just make the browser load those larger images into the cache in the background, like this:

(function($) {
  var cache = [];
  // Arguments are image paths relative to the current page.
  $.preLoadImages = function() {
    var args_len = arguments.length;
    for (var i = args_len; i--;) {
      var cacheImage = document.createElement('img');
      cacheImage.src = arguments[i];
      cache.push(cacheImage);
    }
  }
})(jQuery)

$(window).load(function(){
$.preLoadImages(
    "/picture/1.jpg",
    "/picture/2.jpg", //etc.
   );
});

I placed my code in a $(window).load() because this is a background script and it's not essential it even runs at all, it's just to improve performance.

However, I think this script is somehow blocking the CMS's own thumbnail preloading script.

Am I right? And most importantly, is there a way to dictate that my script only run after all other scripts on the page have run?

cheers

Doriandoric answered 23/6, 2010 at 1:10 Comment(0)
K
2

JavaScript is always running, the hover event for example is firing constantly, mousemove, etc...there's no "end" to the script run.

However in your case, this shouldn't block any other preloading...also you can use document.ready here, since you don't actually need images loaded before your code executes.

In fact, you're actually slowing down the page by using window.load instead...since the preloading starts later, when it could be parallelized with other downloads earlier by the browser. Instead use document.ready, like this:

$(function(){
  $.preLoadImages(
    "/picture/1.jpg",
    "/picture/2.jpg", //etc.
   );
});
Krupp answered 23/6, 2010 at 1:13 Comment(11)
thanks nick. that makes sense. However, my script is somehow blocking the thumbnail preloading... I don't know how, but the effect is consistent and significant. Could it be something to do with the limits of the browser connections...?Doriandoric
@Doriandoric - It could, if they're on the same domain, the actual HTTP spec says 2 connections per domain at a time, which IE in particular obeys (others allow pipelining easier). Can give the images a different URL?, for example http://static.mydomain.com/Images/...., this would allow another 'n' number of connections, because it treats it as another domain from www. for example.Krupp
hey Nick, thanks for the extra snippet, I actually tried ready() first, but was getting the block, so then I though window.load() would help, but of course the thumbnails are being loaded async those that wouldn't make a difference... right? maybe I'm completely wrong, I'm assuming it's a block because the thumbnails only load after all my images have loaded in the backgroundDoriandoric
@nick: ahh... ok, yeah, they are all the same domain... hmmmDoriandoric
that's why I was wondering if I could somehow only have my loader run in the background after the thumbnail stuff has run. However, I'd like to do that without having to know anything about the other scripts...Doriandoric
Try setTimeout(function() { $.preLoadImages("/picture/1.jpg", "/picture/2.jpg", //etc. ); }, 20);, does it have the effect you want? Effectively you're just giving a slight buffer for the current thread to execute...of course if you could show their pre-loading code, I could give you a more-sure way to do this :)Krupp
thanks nick. yeah, I've just created a support ticket just to get a direction to their script. I thought about the timeout but it's not as elegant as I'd like..hmmDoriandoric
@Doriandoric - The timeout can even be 0, the goal is to have it start after the current execution thread executes, not that is actually waits an arbitrary amount of time :)Krupp
ahhh... right, I see, yes of course. that's because timeout start a whole different thread, is that why?Doriandoric
@Doriandoric - Good way to think of it...JavScript's actually single-threaded for most things...think of it as getting bumped to the end :)Krupp
ahh... genius! thanks man. Well look, I had a quick test and still doesn't seem to be working, so maybe it's their funky script. I'll play around with it a bit more later and report backDoriandoric
B
2

Scripts are loaded top down, and body onloads are normally appended to existing onloads - so as long as that $(function().. is at the end of the page, it'll be ran last. (last (as per nick's comment) meaning the initial parse/run of the document)

Brickyard answered 23/6, 2010 at 1:13 Comment(3)
This is kind of true, in the case of jQuery (usually) most code is attached to a ready handler, which is executed later, so while it's evaluated/hooked up in that order, the actual work is done later, when the ready event happens.Krupp
thanks dan. So, are you saying I don't need the .ready() or .load()? just call the function at the bottom of the page?Doriandoric
@Doriandoric - For the code you posted, there's no reason to wait for either, if you were doing something that needed DOM elements to be ready, you need document.ready, if you're not messing with any, no need.Krupp

© 2022 - 2024 — McMap. All rights reserved.