From f3039b695be9832e735f763a074f01c1f3895d39 Mon Sep 17 00:00:00 2001 From: Brad Dunbar Date: Thu, 21 Jun 2012 08:43:32 -0400 Subject: [PATCH] Fix #1420 - Lazy load example images. --- docs/js/jquery.lazyload.js | 210 +++++++++++++++++++++++++++++++++++++ index.html | 94 +++++++++-------- 2 files changed, 258 insertions(+), 46 deletions(-) create mode 100644 docs/js/jquery.lazyload.js diff --git a/docs/js/jquery.lazyload.js b/docs/js/jquery.lazyload.js new file mode 100644 index 000000000..9ba461378 --- /dev/null +++ b/docs/js/jquery.lazyload.js @@ -0,0 +1,210 @@ +/* + * Lazy Load - jQuery plugin for lazy loading images + * + * Copyright (c) 2007-2012 Mika Tuupola + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * Project home: + * http://www.appelsiini.net/projects/lazyload + * + * Version: 1.7.2 + * + */ +(function($, window) { + + $window = $(window); + + $.fn.lazyload = function(options) { + var elements = this; + var settings = { + threshold : 0, + failure_limit : 0, + event : "scroll", + effect : "show", + container : window, + data_attribute : "original", + skip_invisible : true, + appear : null, + load : null + }; + + function update() { + var counter = 0; + + elements.each(function() { + var $this = $(this); + if (settings.skip_invisible && !$this.is(":visible")) { + return; + } + if ($.abovethetop(this, settings) || + $.leftofbegin(this, settings)) { + /* Nothing. */ + } else if (!$.belowthefold(this, settings) && + !$.rightoffold(this, settings)) { + $this.trigger("appear"); + } else { + if (++counter > settings.failure_limit) { + return false; + } + } + }); + + } + + if(options) { + /* Maintain BC for a couple of versions. */ + if (undefined !== options.failurelimit) { + options.failure_limit = options.failurelimit; + delete options.failurelimit; + } + if (undefined !== options.effectspeed) { + options.effect_speed = options.effectspeed; + delete options.effectspeed; + } + + $.extend(settings, options); + } + + /* Cache container as jQuery as object. */ + $container = (settings.container === undefined || + settings.container === window) ? $window : $(settings.container); + + /* Fire one scroll event per scroll. Not one scroll event per image. */ + if (0 === settings.event.indexOf("scroll")) { + $container.bind(settings.event, function(event) { + return update(); + }); + } + + this.each(function() { + var self = this; + var $self = $(self); + + self.loaded = false; + + /* When appear is triggered load original image. */ + $self.one("appear", function() { + if (!this.loaded) { + if (settings.appear) { + var elements_left = elements.length; + settings.appear.call(self, elements_left, settings); + } + $("") + .bind("load", function() { + $self + .hide() + .attr("src", $self.data(settings.data_attribute)) + [settings.effect](settings.effect_speed); + self.loaded = true; + + /* Remove image from array so it is not looped next time. */ + var temp = $.grep(elements, function(element) { + return !element.loaded; + }); + elements = $(temp); + + if (settings.load) { + var elements_left = elements.length; + settings.load.call(self, elements_left, settings); + } + }) + .attr("src", $self.data(settings.data_attribute)); + } + }); + + /* When wanted event is triggered load original image */ + /* by triggering appear. */ + if (0 !== settings.event.indexOf("scroll")) { + $self.bind(settings.event, function(event) { + if (!self.loaded) { + $self.trigger("appear"); + } + }); + } + }); + + /* Check if something appears when window is resized. */ + $window.bind("resize", function(event) { + update(); + }); + + /* Force initial check if images should appear. */ + update(); + + return this; + }; + + /* Convenience methods in jQuery namespace. */ + /* Use as $.belowthefold(element, {threshold : 100, container : window}) */ + + $.belowthefold = function(element, settings) { + var fold; + + if (settings.container === undefined || settings.container === window) { + fold = $window.height() + $window.scrollTop(); + } else { + fold = $container.offset().top + $container.height(); + } + + return fold <= $(element).offset().top - settings.threshold; + }; + + $.rightoffold = function(element, settings) { + var fold; + + if (settings.container === undefined || settings.container === window) { + fold = $window.width() + $window.scrollLeft(); + } else { + fold = $container.offset().left + $container.width(); + } + + return fold <= $(element).offset().left - settings.threshold; + }; + + $.abovethetop = function(element, settings) { + var fold; + + if (settings.container === undefined || settings.container === window) { + fold = $window.scrollTop(); + } else { + fold = $container.offset().top; + } + + return fold >= $(element).offset().top + settings.threshold + $(element).height(); + }; + + $.leftofbegin = function(element, settings) { + var fold; + + if (settings.container === undefined || settings.container === window) { + fold = $window.scrollLeft(); + } else { + fold = $container.offset().left; + } + + return fold >= $(element).offset().left + settings.threshold + $(element).width(); + }; + + $.inviewport = function(element, settings) { + return !$.rightofscreen(element, settings) && !$.leftofscreen(element, settings) && + !$.belowthefold(element, settings) && !$.abovethetop(element, settings); + }; + + /* Custom selectors for your convenience. */ + /* Use as $("img:below-the-fold").something() */ + + $.extend($.expr[':'], { + "below-the-fold" : function(a) { return $.belowthefold(a, {threshold : 0, container: window}); }, + "above-the-top" : function(a) { return !$.belowthefold(a, {threshold : 0, container: window}); }, + "right-of-screen": function(a) { return $.rightoffold(a, {threshold : 0, container: window}); }, + "left-of-screen" : function(a) { return !$.rightoffold(a, {threshold : 0, container: window}); }, + "in-viewport" : function(a) { return !$.inviewport(a, {threshold : 0, container: window}); }, + /* Maintain BC for couple of versions. */ + "above-the-fold" : function(a) { return !$.belowthefold(a, {threshold : 0, container: window}); }, + "right-of-fold" : function(a) { return $.rightoffold(a, {threshold : 0, container: window}); }, + "left-of-fold" : function(a) { return !$.rightoffold(a, {threshold : 0, container: window}); } + }); + +})(jQuery, window); diff --git a/index.html b/index.html index 962dd34a9..f8cd801e6 100644 --- a/index.html +++ b/index.html @@ -2515,7 +2515,7 @@

Examples

- Todos + Todos
@@ -2532,7 +2532,7 @@

DocumentCloud

- DocumentCloud Workspace + DocumentCloud Workspace
@@ -2553,7 +2553,7 @@

Rdio

- Rdio + Rdio
@@ -2574,7 +2574,7 @@

LinkedIn Mobile

- LinkedIn Mobile + LinkedIn Mobile
@@ -2589,7 +2589,7 @@

Flow

- Flow + Flow
@@ -2607,7 +2607,7 @@

AudioVroom

- AudioVroom + AudioVroom
@@ -2623,7 +2623,7 @@

Foursquare

- Foursquare + Foursquare
@@ -2644,7 +2644,7 @@

Wunderkit

- Wunderkit + Wunderkit
@@ -2664,7 +2664,7 @@

Khan Academy

- Khan Academy + Khan Academy
@@ -2682,7 +2682,7 @@

Do

- Do + Do
@@ -2699,24 +2699,24 @@

Pitchfork

- Pitchfork + Pitchfork
- +

Spin

- +

- Spin pulls in the - latest news stories from - their internal API onto their site using Backbone models and collections, and a - custom sync method. Because the music should never stop playing, + Spin pulls in the + latest news stories from + their internal API onto their site using Backbone models and collections, and a + custom sync method. Because the music should never stop playing, even as you click through to different "pages", Spin uses a Backbone router for navigation within the site.

- Spin + Spin
@@ -2737,7 +2737,7 @@

Walmart Mobile

- Walmart Mobile + Walmart Mobile
@@ -2759,7 +2759,7 @@

Groupon Now!

- Groupon Now! + Groupon Now!
@@ -2775,7 +2775,7 @@

Basecamp Mobile

- Basecamp Mobile + Basecamp Mobile
@@ -2796,7 +2796,7 @@

Slavery Footprint

- Slavery Footprint + Slavery Footprint
@@ -2816,7 +2816,7 @@

Stripe

- Stripe + Stripe
@@ -2833,7 +2833,7 @@

Airbnb Mobile

- Airbnb-Mobile + Airbnb-Mobile
@@ -2849,7 +2849,7 @@

Diaspora

- Diaspora + Diaspora
@@ -2876,7 +2876,7 @@

SoundCloud Mobile

- SoundCloud + SoundCloud
@@ -2894,7 +2894,7 @@

Art.sy

- Art.sy + Art.sy
@@ -2911,7 +2911,7 @@

Pandora

- Pandora + Pandora
@@ -2935,7 +2935,7 @@

Inkling

- Inkling + Inkling
@@ -2955,7 +2955,7 @@

Code School

- Code School + Code School
@@ -2974,7 +2974,7 @@

CloudApp

- CloudApp + CloudApp
@@ -2990,7 +2990,7 @@

SeatGeek

- SeatGeek + SeatGeek
@@ -3008,7 +3008,7 @@

Easel

- Easel + Easel
@@ -3022,7 +3022,7 @@

Grove.io

- Grove.io + Grove.io
@@ -3039,7 +3039,7 @@

KANO/GAMES

- KANO/GAMES + KANO/GAMES
@@ -3058,7 +3058,7 @@

Shortmail

- Shortmail + Shortmail
@@ -3076,7 +3076,7 @@

scroll kit

- scroll kit + scroll kit
@@ -3092,7 +3092,7 @@

Battlefield Play4Free

- Battlefield Play4Free + Battlefield Play4Free
@@ -3109,7 +3109,7 @@

Salon.io

- Salon.io + Salon.io
@@ -3130,7 +3130,7 @@

TileMill

- TileMill + TileMill
@@ -3146,7 +3146,7 @@

Blossom

- Blossom + Blossom
@@ -3165,7 +3165,7 @@

Decide

- Decide + Decide
@@ -3182,7 +3182,7 @@

Trello

- Trello + Trello
@@ -3204,7 +3204,7 @@

Ducksboard

- Ducksboard + Ducksboard
@@ -3221,7 +3221,7 @@

QuietWrite

- QuietWrite + QuietWrite
@@ -3246,7 +3246,7 @@

Tzigla

- Tzigla + Tzigla
@@ -3846,6 +3846,7 @@

Change Log

+ @@ -3859,6 +3860,7 @@

Change Log

eval($(code).text()); }); }); + $('[data-original]').lazyload(); });