Browse Source

Initial commit

pull/4/head v1.0.0
Todd Motto 12 years ago
commit
9847e92699
  1. 20
      .editorconfig
  2. 4
      .gitignore
  3. 22
      .jshintrc
  4. 5
      .travis.yml
  5. 87
      Gruntfile.js
  6. 54
      README.md
  7. 94
      dist/echo.js
  8. 10
      dist/echo.min.js
  9. 22
      package.json
  10. 85
      src/echo.js

20
.editorconfig

@ -0,0 +1,20 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
# Change these settings to your own preference
indent_style = space
indent_size = 2
# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

4
.gitignore vendored

@ -0,0 +1,4 @@
node_modules
.DS_Store
.tmp
.sass-cache

22
.jshintrc

@ -0,0 +1,22 @@
{
"node": true,
"browser": true,
"es5": true,
"esnext": true,
"bitwise": true,
"camelcase": true,
"curly": true,
"eqeqeq": true,
"immed": true,
"indent": 2,
"latedef": true,
"newcap": true,
"noarg": true,
"quotmark": "single",
"regexp": true,
"undef": true,
"unused": true,
"strict": true,
"trailing": false,
"smarttabs": true
}

5
.travis.yml

@ -0,0 +1,5 @@
language: node_js
node_js:
- "0.11"
- "0.10"
- "0.8"

87
Gruntfile.js

@ -0,0 +1,87 @@
/*!
* Gruntfile.js configuration
*/
'use strict';
module.exports = function ( grunt ) {
/*
* Dynamically load the npm tasks
*/
require( 'matchdep' ).filterDev('grunt-*').forEach( grunt.loadNpmTasks );
/*
* Grunt init
*/
grunt.initConfig({
/*
* Grunt JSON for project
*/
pkg: grunt.file.readJSON( 'package.json' ),
/*
* Credit banner
*/
tag: {
banner: "/*!\n" +
" * <%= pkg.title %>\n" +
" * @version <%= pkg.version %>\n" +
" * @author <%= pkg.author[0].name %> <%= pkg.author[1].url %>\n" +
" * Project: <%= pkg.homepage %>\n" +
" *\n" +
" * <%= pkg.description %>\n" +
" * Copyright <%= pkg.year %>." +
" <%= pkg.licenses[0].type %> licensed.\n" +
" */\n"
},
/*
* jsHint
*/
jshint: {
files: ["src/echo.js"],
options: {
jshintrc: ".jshintrc"
}
},
/*
* Concat
*/
concat: {
dist: {
src: ["src/echo.js"],
dest: "dist/echo.js"
},
options: {
banner: "<%= tag.banner %>"
}
},
/*
* UglifyJS
*/
uglify: {
files: {
src: ["dist/echo.js"],
dest: "dist/echo.min.js"
},
options: {
banner: "<%= tag.banner %>"
}
}
});
/*
* Register tasks
*/
grunt.registerTask("default", [
"jshint",
"concat",
"uglify"
]);
};

54
README.md

@ -0,0 +1,54 @@
# Echo [![Build Status](https://travis-ci.org/toddmotto/echo.png)](https://travis-ci.org/toddmotto/echo)
```html
<img src="img/blank.gif" alt="Photo" data-echo="img/photo.jpg">
```
## Demo
Check out a [demo of Echo](http://toddmotto.com/labs/echo).
## Installing with Bower
To install Echo into your project using Bower, use the GitHub repository hook:
```
bower install https://github.com/toddmotto/echo.git
```
## Manual installation
Drop your files into your required folders, make sure you're using the file(s) from the `dist` folder, which is the compiled production-ready code. Ensure you place the script before the closing `</body>` tag so the DOM tree is populated when the script runs.
```html
<body>
<!-- html content above -->
<script src="dist/echo.js"></script>
</body>
```
## Configuring Echo
Echo config is super-simple, just add the image that needs to load when visible in a `data-echo` attribute:
```html
<img src="img/blank.gif" alt="Photo" data-echo="img/photo.jpg">
```
## Scaffolding
Project files and folder structure.
```
├── dist/
│ ├── echo.js
│ └── echo.min.js
├── src/
│ └── echo.js
├── .editorconfig
├── .gitignore
├── .jshintrc
├── .travis.yml
├── Gruntfile.js
└── package.json
```
## License
MIT license

94
dist/echo.js vendored

@ -0,0 +1,94 @@
/*!
* Echo
* @version 1.0.0
* @author Todd Motto http://toddmotto.com
* Project: https://github.com/toddmotto/echo
*
* Raw JavaScript lazy-loading images with HTML5 data-* attributes.
* Copyright 2013. MIT licensed.
*/
window.echo = (function (window, document) {
'use strict';
/*
* Constructor function
*/
var Echo = function (elem) {
this.elem = elem;
this.render();
this.listen();
};
/*
* Images for echoing
*/
var echoStore = [];
/*
* Element in viewport logic
*/
var scrolledIntoView = function (element) {
var coords = element.getBoundingClientRect();
return ((coords.top >= 0 && coords.left >= 0 && coords.top) <= (window.innerHeight || document.documentElement.clientHeight));
};
/*
* Changing src attr logic
*/
var echoSrc = function (img, callback) {
img.src = img.getAttribute('data-echo');
if (callback) {
callback();
}
};
/*
* Remove loaded item from array
*/
var removeEcho = function (element, index) {
if (echoStore.indexOf(element) !== -1) {
echoStore.splice(index, 1);
}
};
/*
* Echo the images and callbacks
*/
var echoImages = function () {
for (var i = 0; i < echoStore.length; i++) {
var self = echoStore[i];
if (scrolledIntoView(self)) {
echoSrc(self, removeEcho(self, i));
}
}
};
/*
* Prototypal setup
*/
Echo.prototype = {
init : function () {
echoStore.push(this.elem);
},
render : function () {
if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', echoImages, false);
} else {
window.onload = echoImages;
}
},
listen : function () {
window.onscroll = echoImages;
}
};
/*
* Initiate the plugin
*/
var lazyImgs = document.querySelectorAll('img[data-echo]');
for (var i = 0; i < lazyImgs.length; i++) {
new Echo(lazyImgs[i]).init();
}
})(window, document);

10
dist/echo.min.js vendored

@ -0,0 +1,10 @@
/*!
* Echo
* @version 1.0.0
* @author Todd Motto http://toddmotto.com
* Project: https://github.com/toddmotto/echo
*
* Raw JavaScript lazy-loading images with HTML5 data-* attributes.
* Copyright 2013. MIT licensed.
*/
window.echo=function(a,b){"use strict";var c=function(a){this.elem=a,this.render(),this.listen()},d=[],e=function(c){var d=c.getBoundingClientRect();return(d.top>=0&&d.left>=0&&d.top)<=(a.innerHeight||b.documentElement.clientHeight)},f=function(a,b){a.src=a.getAttribute("data-echo"),b&&b()},g=function(a,b){-1!==d.indexOf(a)&&d.splice(b,1)},h=function(){for(var a=0;a<d.length;a++){var b=d[a];e(b)&&f(b,g(b,a))}};c.prototype={init:function(){d.push(this.elem)},render:function(){b.addEventListener?b.addEventListener("DOMContentLoaded",h,!1):a.onload=h},listen:function(){a.onscroll=h}};for(var i=b.querySelectorAll("img[data-echo]"),j=0;j<i.length;j++)new c(i[j]).init()}(window,document);

22
package.json

@ -0,0 +1,22 @@
{
"name": "Echo",
"title": "Echo",
"description": "Raw JavaScript lazy-loading images with HTML5 data-* attributes.",
"author": [
{ "name" : "Todd Motto" },
{ "url" : "http://toddmotto.com" }
],
"homepage": "https://github.com/toddmotto/echo",
"licenses": [
{ "type": "MIT" }
],
"year" : "2013",
"version": "1.0.0",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-uglify": "~0.2.0",
"grunt-contrib-jshint": "~0.4.3",
"matchdep": "~0.1.2"
}
}

85
src/echo.js

@ -0,0 +1,85 @@
window.echo = (function (window, document) {
'use strict';
/*
* Constructor function
*/
var Echo = function (elem) {
this.elem = elem;
this.render();
this.listen();
};
/*
* Images for echoing
*/
var echoStore = [];
/*
* Element in viewport logic
*/
var scrolledIntoView = function (element) {
var coords = element.getBoundingClientRect();
return ((coords.top >= 0 && coords.left >= 0 && coords.top) <= (window.innerHeight || document.documentElement.clientHeight));
};
/*
* Changing src attr logic
*/
var echoSrc = function (img, callback) {
img.src = img.getAttribute('data-echo');
if (callback) {
callback();
}
};
/*
* Remove loaded item from array
*/
var removeEcho = function (element, index) {
if (echoStore.indexOf(element) !== -1) {
echoStore.splice(index, 1);
}
};
/*
* Echo the images and callbacks
*/
var echoImages = function () {
for (var i = 0; i < echoStore.length; i++) {
var self = echoStore[i];
if (scrolledIntoView(self)) {
echoSrc(self, removeEcho(self, i));
}
}
};
/*
* Prototypal setup
*/
Echo.prototype = {
init : function () {
echoStore.push(this.elem);
},
render : function () {
if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', echoImages, false);
} else {
window.onload = echoImages;
}
},
listen : function () {
window.onscroll = echoImages;
}
};
/*
* Initiate the plugin
*/
var lazyImgs = document.querySelectorAll('img[data-echo]');
for (var i = 0; i < lazyImgs.length; i++) {
new Echo(lazyImgs[i]).init();
}
})(window, document);
Loading…
Cancel
Save