ActionsDev
21 replies to this thread. Most Recent
Michael Henry
27 May 2010, 12:09 am
[Pro] LazyLoad JQuery
What’s the most efficient way to add a lazyload jquery effect to a website. http://www.appelsiini.net/projects/lazyload/enabled_fadein.html
Is it better to use Mootool version? http://davidwalsh.name/js/lazyload
waltd
27 May 2010, 3:35 amIf you’re going to do anything else in Freeway (use the effects built in to the app, or the like) then you should use a Prototype-based effect. Here’s how to make a lazy loader for Prototype in Freeway.
- Lay out your incredibly tall page.
- Make your “loading” image to replace any images below the fold. I used http://ajaxload.com to make a nice spinner in white on gray, then placed it in a gray image box above the top of the page. Preview into a text editor, or view source in a browser, and figure out what the path is to your loading image — mine was ‘Resources/ajaxloader2.gif’.
- Apply the Protaculous Action to the page, and select the prototype-packed library.
- Copy this code: http://pastie.org/979332.txt
- Back in Freeway, click on a blank spot on the page so the page itself is selected, then click on the top Function Body button in the Actions palette. Paste the code in.
- Before you close the dialog, make sure the last line is correct — that’s where you specify your loading image.
Preview this in a browser, or better, from your server. The images below the fold will be replaced with the placeholder image until they scroll into view, then their original images will load in.
Walter
Freeway user since 1997
Paul Everett
27 May 2010, 4:07 amWalter, thanks for that. Will do tonight. I am working on another image gallery, just not sure what to choose, I want to have it rollover thumb then image area as per existing site… though this will still make for a large download too?
Paul Everett
27 May 2010, 7:27 amOk doing it now, does this effect it or should I now remove this from my last exercise? <script src=”http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js ” type=”text/javascript” charset=”utf-8”> </script> <script type=”text/javascript”> document.observe(‘dom:loaded’, function(evt){ $(‘PageDiv’).hide(); }); Event.observe(window, ‘load’, function(evt){ $(‘PageDiv’).show(); }); </script>
also like scriptylightbox, how would I implement a transparent div, that covers the page until it has finished loading? is it a transparent div?
also while I am draining you… I really do appreciate all this what gallery method that has rollovers like current design though maybe fade in would you suggest that could help with the loading of the page.
My page loading only takes about 2-3 seconds if that… (with caches cleared)
waltd
27 May 2010, 10:09 amYou should remove that, because it’s just going to fight with the rest of it.
Walter
On May 27, 2010, at 3:27 AM, Paul Everett wrote:
Ok doing it now, does this effect it or should I now remove this from my last exercise? <script src=”http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js > ” type=”text/javascript” charset=”utf-8”> </script> <script type=”text/javascript”> document.observe(‘dom:loaded’, function(evt){ $ (‘PageDiv’).hide(); }); Event.observe(window, ‘load’, function(evt){ $ (‘PageDiv’).show(); }); </script>
also like scriptylightbox, how would I implement a transparent div, that covers the page until it has finished loading? is it a transparent div?
also while I am draining you… I really do appreciate all this what gallery method that has rollovers like current design though maybe fade in would you suggest that could help with the loading of the page.
My page loading only takes about 2-3 seconds if that… (with caches cleared)
Freeway user since 1997
Paul Everett
27 May 2010, 10:35 amWalter, 1. when you state place the image box (graphic box or html box with graphic inside)? 2. gray image box above the top of the page.(place above - as in pastboard?)
thanks
Paul Everett
27 May 2010, 11:25 amimmm…. does not really work as I think it is conflicting. http://concretecreative.co.nz/test/portfolio-labels.html
Paul Everett
27 May 2010, 11:28 amsorry brain not functioning… and my browser loads too fast… though I just saw the light!! yes it does I get it now… will change the loader… jeppers
waltd
27 May 2010, 11:39 amIt’s there, and it’s working, but not the way you think. This particular lazy loading implementation works by observing the current position of the image vertically with respect to the browser window. If the image is high enough in the page to appear on screen, then it will load in its default content.
If you were to make your page really tall, and therefore if the bulk of the photos on screen were “below the fold”, then you would find that the photos that were off screen would be repeat instances of the loading image you positioned (yes, on the pasteboard) off-screen.
I’ll have a look at the math inside this function (which I simply Googled for and cleaned up a little to conform to modern Prototype code practices) and see if I can determine if an image is off-screen to the right or left. That would probably help in your case, because the hidden parts of a carousel are entirely off screen to the right, at least for most normal screens. But I won’t have time to look at this today.
What you could try right now is to switch your Carousel from horizontal (default) to vertical. That will cause the layout to become ridiculously tall, and trigger the effect.
One last note: the way this is implemented will naturally work so quickly on a local (preview) page that you might not notice it working. Unlike some loaders I have seen, this one doesn’t use an Ajax call (and all of its overhead) to load in the real image, so the effect can happen so quickly that you don’t see it working, and you might be tempted to think it isn’t working. Best to test it on a server, and over a slow connection, if such a thing can be found any more.
Walter
Freeway user since 1997
Paul Everett
27 May 2010, 11:42 amYep slow connection hard to find. Ok will do thanks again.
Paul Everett
27 May 2010, 11:47 amHi I managed to get split second view, it resizes the animated gif to the size of any image on the page, quite large.
waltd
27 May 2010, 6:08 pmOn 27 May 2010, 11:47 am, Paul wrote:
Hi I managed to get split second view, it resizes the animated gif to the size of any image on the page, quite large.
What I did to work around this was to place the animated GIF in Freeway in a much larger box, then filled that box with the background color of the animation. So my box is #cccccc, and the spinner is white, and the spinner is centered neatly on the photo placeholder. Freeway can modify animated GIFs like this without destroying their animation properties. It’s one of the silly tricks I used to use when demonstrating Freeway at Macworld. (Layer a JPEG with an animated GIF, and press Preview — instant merged animated GIF with animation still playing.)

Walter
Freeway user since 1997
Paul Everett
28 May 2010, 5:24 amHi Walter, OK, test site here: http://concretecreative.co.nz/test/portfolio.html not working that well with the Carousel. Get a spinner… also seems to still resize it? Should I make the preloader larger?
Q: I am thinking of making the gallery a rollover rather than Carousel though still will; have the same loading issues right?
Please too all cool with doing something different, don’t want to take up too much of your time, don’t know you manage to do it all really?
really do appreciate all help, you rock.
waltd
28 May 2010, 12:18 pmOkay. That makes sense. The effect isn’t firing off because the window hasn’t scrolled anywhere, which is the event that triggers it. Try this: change the options block in the last line of the script from
{placeholder:'Resources/ajaxloader2.gif'}
to
{placeholder:'Resources/ajaxloader2.gif',event:'click'}
Walter
On May 28, 2010, at 1:23 AM, Paul Everett wrote:
Hi Walter, OK, test site here: http://concretecreative.co.nz/test/ portfolio.html not working that well with the Carousel. Get a spinner… also seems to still resize it? Should I make the preloader larger?
Q: I am thinking of making the gallery a rollover rather than Carousel though still will; have the same loading issues right?
Please too all cool with doing something different, don’t want to take up too much of your time, don’t know you manage to do it all really?
really do appreciate all help, you rock.
Freeway user since 1997
Paul Everett
28 May 2010, 11:28 pmHi, now that effect all graphic, remove images leaving preloader only
will leave… I think. thanks though all appreciated.
waltd
2 Jun 2010, 6:34 pmI found another way to do this, which doesn’t rely on you telling it what event to observe at all. Same method as before, apply Protaculous to the page, use prototype-packed as the library, and paste this into the first Function Body dialog:
var in_viewport = function(elm){
var offsets = elm.viewportOffset();
var port = {left:document.viewport.getScrollOffsets()[0],right:document.viewport.getWidth(),top:document.viewport.getScrollOffsets()[1],bottom:document.viewport.getScrollOffsets()[1] + document.viewport.getHeight()};
var box = {left:offsets[0],right:offsets[0] + elm.getWidth(),top:offsets[1],bottom:offsets[1] + elm.getHeight()};
if(box.right > port.left && box.left < port.right && box.bottom > port.top && box.top < port.bottom) return true; if(box.left < port.right && box.right > port.left && box.bottom > port.top && box.top < port.bottom) return true;
return false;
}
Element.addMethods({
lazyload: function(element, options){
var element = $(element);
var options = Object.extend({
placeholder : 'Resources/_clear.gif',
frequency : 0.2
}, options || {}
);
var remove_placeholder = function (){
// this function restores the original image source; called when within the viewport
if ( true === element.hasAttribute('_src') ){
var old_source = $(element).readAttribute('_src');
element.writeAttribute({ src: old_source });
element.writeAttribute({ _src: null });
}
}
var old_source = $(element).readAttribute('src');
var new_source = options.placeholder;
element.writeAttribute({ src : new_source }).writeAttribute({ '_src' : old_source });
var pe = new PeriodicalExecuter(function(){
if(in_viewport(element)){
remove_placeholder();
pe.stop();
}
}, options.frequency);
}
});
$$('img').invoke('lazyload',{placeholder:'Resources/ajaxloader2.gif'});
Remember to change the name of the “loading” image to the one you have placed on your pasteboard somewhere, or just leave the entire options block out to use the Freeway _clear.gif instead.
What this method does is “hook” all images on the page. If they’re off-screen (for any reason — so this works with Carousel, too), they get replaced with the loading image. If any edge or corner of an image is on-screen by as much as one pixel, it will be swapped with its “real” image. Every two tenths of a second, each image checks itself again to be sure. Once an image has been replaced, it calls off this checking process. Once all images have loaded, no further activity is taken on the page.
Walter
Freeway user since 1997
Paul Everett
4 Jun 2010, 9:18 pmWalter thanks… will try later and post result
Paul Everett
6 Jun 2010, 3:31 am@Walter. I have updated… http://www.tlprint.co.nz/portfolio.html have used the _clear.gif as the ajaxloader.gif gets a little stretched… and too many loading. Would prefer though if it would only work on the carousel/portfolio images and not the website logo and other main elements.
thanks again.
waltd
6 Jun 2010, 4:42 pmOkay, you can restrict it to only the large images hidden inside the Carousel if you like (actually, you can get really fine-grained about this because of how the effect gets attached to images).
Where the code reads $$('img'), you simply include the ID of your Carousel. If you click on the main Carousel element on your page, you’ll see its ID in the Name field in the Inspector. The Carousel Action uses that ID as the base for the ID of the main outer DIV it creates as the parent element for the effect.
So in your example page above, the ID of the main Carousel is pgallery1, so the ID you want is carousel_pgallery1.
Make your accessor code read $$('#carousel_pgallery1 img') and now the lazy-loader will only affect the large images inside your carousel.
If you also wanted the thumbnail images to be lazy-loaded, you could make the accessor code $$('#carousel_pgallery1 img, .controls img'). Nothing else on the page will be affected.
Walter
Freeway user since 1997
Paul Everett
7 Jun 2010, 6:22 am@Walter: Nice… thanks have done this. Thanks again for your help.
