Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local checkImages function instead of triggering events on the container #22

Closed
wants to merge 10 commits into from
87 changes: 87 additions & 0 deletions enabled_container_belowthefold.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<!DOCTYPE html>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Lazy Load Enabled on Container</title>

<link href="http://www.appelsiini.net/stylesheets/main2.css" rel="stylesheet" type="text/css" />
<style type="text/css">
#sidebar {
width: 0px;
}

#content {
width: 804px;
}

#container {
height: 600px;
margin-top: 1000px;
overflow: scroll;
}
</style>
</head>

<body>
<div id="wrap">
<div id="header">
<p>
<h1>Lazy Load</h1><br />
<small>Image lazy loader plugin for jQuery.</small>
<ul id="nav">
<li id="first"><a href="/" class="active">weblog</a></li>
<li><a href="/projects" class="last">projects</a></li>
</ul>
</p>
</div>
<div id="content">

<h2>Plugin enabled on container</h2>
<div class="entry">

<p>
Images below the visible area (the ones lower than container bottom) are not loaded. When scrolling down
they are loaded when needed. Empty cache and shift-reload to test again. Compare this to page where plugin is
<a href="disabled.html">disabled</a> or same page with <a href="enabled_fadein.html">fadein effect</a>.
</p>

<code>
<pre>
$("img").lazyload({
effect : "fadeIn",
container: $("#container")
});</pre>
</code>

<div id="container">
<img src="img/grey.gif" data-original="img/bmw_m1_hood.jpg" width="765" height="574" alt="BMW M1 Hood"><br/>
<img src="img/grey.gif" data-original="img/bmw_m1_side.jpg" width="765" height="574" alt="BMW M1 Side"><br/>
<img src="img/grey.gif" data-original="img/viper_1.jpg" width="765" height="574" alt="Viper 1"><br/>
<img src="img/grey.gif" data-original="img/viper_corner.jpg" width="765" height="574" alt="Viper Corner"><br/>
<img src="img/grey.gif" data-original="img/bmw_m3_gt.jpg" width="765" height="574" alt="BMW M3 GT"><br/>
<img src="img/grey.gif" data-original="img/corvette_pitstop.jpg" width="765" height="574" alt="Corvette Pitstop"><br/>
</div>

</div>
<div id="sidebar">

</div>

<div id="footer">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script src="jquery.lazyload.js?v=3" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
$(function() {
$("img").lazyload({effect : "fadeIn", container: $("#container")});
});
</script>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script>
<script type="text/javascript">
_uacct = "UA-190966-1";
urchinTracker();
</script>

</body>
</html>
169 changes: 109 additions & 60 deletions jquery.lazyload.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
*
*/
(function($, window) {

$window = $(window);

$.fn.lazyload = function(options) {
var elements = this;
var alternate_container = false;
var settings = {
threshold : 0,
failure_limit : 0,
Expand All @@ -28,8 +30,43 @@
appear : null,
load : null
};

if(options) {

var checkImages = function(check_window) {
var counter = 0;
var window_settings = {
container: window,
threshold: 0
};

elements.each(function() {
var $this = $(this);
if (settings.skip_invisible && !$this.is(":visible")) {return;}

if ($this.loaded ||
$.abovethetop(this, settings) ||
$.leftofbegin(this, settings) ||
(check_window && (
$.abovethetop(this, window_settings) ||
$.leftofbegin(this, window_settings)
))) {
/* Nothing. */
} else if (!(
$.belowthefold(this, settings) ||
$.rightoffold(this, settings) ||
(check_window && (
$.belowthefold(this, window_settings) ||
$.rightoffold(this, window_settings)
)))) {
$this.trigger("appear");
} else {
if (++counter > settings.failure_limit) {
return false;
}
}
});
};

if (options) {
/* Maintain BC for a couple of version. */
if (undefined !== options.failurelimit) {
options.failure_limit = options.failurelimit;
Expand All @@ -39,129 +76,141 @@
options.effect_speed = options.effectspeed;
delete options.effectspeed;
}


if (options.container && options.container !== window) {
alternate_container = true;
}

$.extend(settings, options);
}

/* Fire one scroll event per scroll. Not one scroll event per image. */
var elements = this;
if (0 == settings.event.indexOf("scroll")) {
if (0 === settings.event.indexOf("scroll")) {
$(settings.container).bind(settings.event, function(event) {
var counter = 0;
elements.each(function() {
$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;
}
}
});
return checkImages(alternate_container);
});

if (alternate_container) {
$(window).bind(settings.event, function(event) {
return checkImages(alternate_container);
});
}
}

this.each(function() {
var self = this;
var $self = $(self);

self.loaded = false;

/* When appear is triggered load original image. */
$self.one("appear", function() {
var elements_left;

if (!this.loaded) {
if (settings.appear) {
var elements_left = elements.length;
elements_left = elements.length;
settings.appear.call(self, elements_left, settings);
}
$("<img />")
.bind("load", function() {
$self
.hide()
var elements_left, temp;

$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) {
temp = $.grep(elements, function(element) {
return !element.loaded;
});
elements = $(temp);

if (settings.load) {
var elements_left = elements.length;
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")) {
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) {
$(settings.container).trigger(settings.event);
checkImages(alternate_container);
});

/* Force initial check if images should appear. */
$(settings.container).trigger(settings.event);

return this;
checkImages(alternate_container);

return this;
};

/* Convenience methods in jQuery namespace. */
/* Use as $.belowthefold(element, {threshold : 100, container : window}) */

$.belowthefold = function(element, settings) {
var $container, fold;

if (settings.container === undefined || settings.container === window) {
var fold = $window.height() + $window.scrollTop();
fold = $window.height() + $window.scrollTop();
} else {
var fold = $(settings.container).offset().top + $(settings.container).height();
$container = $(settings.container);
fold = $container.offset().top + $container.height();
}

return fold <= $(element).offset().top - settings.threshold;
};

$.rightoffold = function(element, settings) {
var $container, fold;

if (settings.container === undefined || settings.container === window) {
var fold = $window.width() + $window.scrollLeft();
fold = $window.width() + $window.scrollLeft();
} else {
var fold = $(settings.container).offset().left + $(settings.container).width();
$container = $(settings.container);
fold = $container.offset().left + $container.width();
}

return fold <= $(element).offset().left - settings.threshold;
};

$.abovethetop = function(element, settings) {
var fold;
var $element = $(element);

if (settings.container === undefined || settings.container === window) {
var fold = $window.scrollTop();
fold = $window.scrollTop();
} else {
var fold = $(settings.container).offset().top;
fold = $(settings.container).offset().top;
}
return fold >= $(element).offset().top + settings.threshold + $(element).height();

return fold >= $element.offset().top + settings.threshold + $element.height();
};

$.leftofbegin = function(element, settings) {
var fold;
var $element = $(element);

if (settings.container === undefined || settings.container === window) {
var fold = $window.scrollLeft();
fold = $window.scrollLeft();
} else {
var fold = $(settings.container).offset().left;
fold = $(settings.container).offset().left;
}
return fold >= $(element).offset().left + settings.threshold + $(element).width();

return fold >= $element.offset().left + settings.threshold + $element.width();
};

$.inviewport = function(element, settings) {
Expand All @@ -173,15 +222,15 @@
/* 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}) },
"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}) }
"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);
2 changes: 1 addition & 1 deletion jquery.lazyload.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.