jQuery - Lazy loading images

The jQuery Lazy loader plugin, as been around for a long old while and I've been aware of it, though never really given it a good poke, mostly due to the big fat warning at the top of the page saying "this doesn't work".

Having seen a few sites which use it, this plugin still doesn't work. Browsers still "front load" all of the content, then once you scroll and the image you're lazy loading comes into view, it downloads the image again.

So this isn't too awesome, but not useless. If you've got a site which you can require that Javascript be on, any images which you want to lazy load should start out with a placeholder image, e.g.

<div class="listing">
  <div class="row">
    <div class="image"><img src="placeholder-image.gif" original="path-to-giant-image.jpg" class="lazy-load" alt="" /></div>
    <div class="text">
      <h3>Hello world article</h3>
      <p>Lorem ipsum etcerum...</p>

With the JS being something like:

$(function() {
  $("img.lazy-load").lazyload({effect: 'fadeIn'});

To this end, I've come across a modified version of the aforementioned plugin which does exactly that. It works, but the obvious limitation is that if you don't have javascript turned on you won't see any images.

Here's the code for the plugin

// Adapted Lazy load plugin from http://www.appelsiini.net/projects/lazyload

(function ($) {
    var $window = $(window);
    $.fn.lazyload = function (options) {
        var didScroll = false;
        var options = $.extend({
            threshold: 100,
            effect: "show",
            effectspeed: 0
        }, options || {});
        var elements = this;
        var load = function () {
                elements.each(function () {
                    var self = $(this);
                    if (!isBelowFold(self, options)) {
        $window.bind("scroll", function () {
            didScroll = true
        setInterval(function () {
            if (didScroll) {
                didScroll = false;
        }, 400);
        return elements.each(function () {
            var self = $(this),
                src = self.attr("data-src");
            self.one("appear", function () {
                $("").bind("load", function () {
                    self.hide().attr("src", src)[options.effect](options.effectspeed);
                    self.data("loaded", true);
                    var temp = $.grep(elements, function (item) {
                        return !$(item).data("loaded")
                    if (temp.length == 0) {
                        $window.unbind("scroll", load)
                }).attr("src", src)
            if (!isBelowFold(self, options)) {
            } else {
                self.data("loaded", false)
    var isBelowFold = function (element, options) {
            var fold = $window.scrollTop() + $window.height(),
                imgPos = element.offset().top;
            return imgPos >= (fold + options.threshold) || false