Skip to content

Commit

Permalink
Went back to variable refs.
Browse files Browse the repository at this point in the history
  • Loading branch information
malchata committed Aug 13, 2017
1 parent 3aab5f3 commit f1fc170
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 34 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# yall.js (Yet Another Lazy Loader)
### (Y'all need to lazy load images)

yall.js is a very small image lazy loader for reasonably modern browsers (back to IE10) that weighs in at 1.24 KB uglified (621 bytes with gzip/507 bytes with Brotli). It depends on `classList`, `querySelectorAll`, supports the `<picture>` element and the `srcset` attribute. yall.js also uses `IntersectionObserver` if available, but will fall back to more traditional means if it's not. If you want to try out yall.js, grab the copy in the `dist` folder. Or you can clone the repo and check out the `test` folder. If you want to tinker, work with the copy in the `src` folder and build using `npm run build` (requires `npx`).
yall.js is a very small image lazy loader for reasonably modern browsers (back to IE10) that weighs in at 1.09 KB uglified (657 bytes with gzip/554 bytes with Brotli). It depends on `classList`, `querySelectorAll`, and supports the `<picture>` element and `srcset`. yall.js will also use `IntersectionObserver` if available, but will fall back to more traditional means if it's not. If you want to try out yall.js, grab the copy in the `dist` folder. Or you can clone the repo and check out the `test` folder. If you want to tinker, work with the copy in the `src` folder and build using `npm run build` (requires `npx`).

## Usage Pattern

Expand Down
2 changes: 1 addition & 1 deletion dist/yall-1.1.1.min.js

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

1 change: 0 additions & 1 deletion dist/yall.min.js

This file was deleted.

10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
"name": "yall",
"version": "1.1.1",
"description": "Yet Another Lazy Loader",
"main": "./src/yall.js",
"scripts": {
"build": "npx uglifyjs --verbose --compress warnings --mangle -o ./dist/yall.js ./src/yall.js"
"clean": "rm -rf ./dist&&mkdir -p ./dist",
"build": "npm run clean&&npx uglifyjs --verbose --toplevel --compress toplevel --mangle toplevel -o ./dist/yall-$(node -p -e \"require('./package.json').version\").min.js $(node -p -e \"require('./package.json').main\")"
},
"repository": {
"type": "git",
"url": "git+https://github.com/malchata/yall.git"
"url": "git+https://github.com/malchata/yall.js.git"
},
"keywords": [
"lazy load",
Expand All @@ -17,9 +19,9 @@
"author": "Jeremy Wagner <[email protected]> (https://jeremywagner.me/)",
"license": "MIT",
"bugs": {
"url": "https://github.com/malchata/yall/issues"
"url": "https://github.com/malchata/yall.js/issues"
},
"homepage": "https://github.com/malchata/yall#readme",
"homepage": "https://github.com/malchata/yall.js#readme",
"devDependencies": {
"uglify-js": "^3.0.27"
},
Expand Down
75 changes: 48 additions & 27 deletions src/yall.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,51 +5,69 @@

(function(window, document){
var
// The primary goal here is to keep this script as small as possible
// while maintaining functionality. The uglifier goes a long way,
// but we can take things a bit farther by saving strings for
// frequently used method and strings.
fe = "forEach",
qsa = "querySelectorAll",
pn = "parentNode",
gbcr = "getBoundingClientRect",
pr = "prototype",
io = "IntersectionObserver",
ioe = io + "Entry",
ln = "length",
dss = "data-srcset",
// Placeholders used for event handler strings.
documentEvents = ["scroll", "touchmove"],
windowEvents = ["orientationchange", "resize"],
// Tracks if yall is currently processing. Used for throttling. Only matters if IntersectionObserver is unsupported.
active = 0,
// Placeholder for elements
elements,
// Replaces target attribute value with source attribute, if applicable
replaceAttr = function(node, sattr, tattr){
var v = node.getAttribute(sattr);
replaceAttr = function(node, sourceAttr, targetAttr){
var v = node.getAttribute(sourceAttr);

if(v){
node[tattr] = v;
node.removeAttribute(sattr);
node[targetAttr] = v;
node.removeAttribute(sourceAttr);
}
},
// The handler to load the image
loadImage = function(img){
if(img.parentNode.tagName == "PICTURE"){
Array.prototype.slice.call(img.parentNode.querySelectorAll("source")).forEach(function(source){
replaceAttr(source, "data-srcset", "srcset");
if(img[pn].tagName == "PICTURE"){
Array[pr].slice.call(img[pn][qsa]("source"))[fe](function(source){
replaceAttr(source, dss, "srcset");
});
}

replaceAttr(img, "data-src", "src");
replaceAttr(img, "data-srcset", "srcset");
replaceAttr(img, dss, "srcset");
img.classList.remove("lazy");
elements.splice(elements.indexOf(img), 1);
},
// A multiple event binding handler.
multiBind = function(obj, handlers, fn, remove){
handlers.forEach(function(handler){
handlers[fe](function(handler){
remove ? obj.removeEventListener(handler, fn) : obj.addEventListener(handler, fn);
});
},
// The guts of the lazy loader (now only used when IntersectionObserver is not supported)
yall = function(){
if(!elements.length){
if(!elements[ln]){
// There are no more elements to lazy load, so we'll unbind everything.
multiBind(document, documentEvents, yall, 1);
multiBind(window, windowEvents, yall, 1);
}

// Check if the lazy loader is active
if(!active){
active = 1;

setTimeout(function(){
elements.forEach(function(img){
if((img.getBoundingClientRect().top <= window.innerHeight && img.getBoundingClientRect().bottom >= 0) && getComputedStyle(img).display != "none"){
elements[fe](function(img){
if((img[gbcr]().top <= window.innerHeight && img[gbcr]().bottom >= 0) && getComputedStyle(img).display != "none"){
loadImage(img);
}
});
Expand All @@ -61,31 +79,34 @@

// Everything's kicked off on DOMContentLoaded
multiBind(document, ["DOMContentLoaded"], function(){
elements = Array.prototype.slice.call(document.querySelectorAll("img.lazy"));
elements = Array[pr].slice.call(document[qsa]("img.lazy"));

if(elements.length){
// We're only going to do stuff if we found `img.lazy` elements
if(elements[ln]){
// This compatibility check has been taken from https://github.com/WICG/IntersectionObserver/blob/gh-pages/polyfill/intersection-observer.js
if("IntersectionObserver" in window && "IntersectionObserverEntry" in window && "intersectionRatio" in IntersectionObserverEntry.prototype){
ob = new IntersectionObserver(function(entries, observer){
entries.forEach(function(entry){
if(io in window && ioe in window && "intersectionRatio" in window[ioe][pr]){
var imageObserver = new window[io](function(entries, observer){
entries[fe](function(entry){
if(entry.isIntersecting){
loadImage(entry.target);
if(!elements.length) observer.disconnect();

if(!elements[ln]){
observer.disconnect();
}
}
});
});

elements.forEach(function(img){
ob.observe(img);
elements[fe](function(img){
imageObserver.observe(img);
});

return;
}

// If IntersectionObserver isn't available, we'll do things the old way.
yall();
multiBind(document, documentEvents, yall);
multiBind(window, windowEvents, yall);
else{
// If IntersectionObserver isn't available, we'll do things the old way.
yall();
multiBind(document, documentEvents, yall);
multiBind(window, windowEvents, yall);
}
}
});
})(window, document);

0 comments on commit f1fc170

Please sign in to comment.