From 9847e92699585576513babcc857f9a0c0b0416d6 Mon Sep 17 00:00:00 2001 From: Todd Motto Date: Sun, 11 Aug 2013 19:48:42 +0100 Subject: [PATCH] Initial commit --- .editorconfig | 20 +++++++++++ .gitignore | 4 +++ .jshintrc | 22 ++++++++++++ .travis.yml | 5 +++ Gruntfile.js | 87 ++++++++++++++++++++++++++++++++++++++++++++ README.md | 54 ++++++++++++++++++++++++++++ dist/echo.js | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ dist/echo.min.js | 10 ++++++ package.json | 22 ++++++++++++ src/echo.js | 85 +++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 403 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .jshintrc create mode 100644 .travis.yml create mode 100644 Gruntfile.js create mode 100644 README.md create mode 100644 dist/echo.js create mode 100644 dist/echo.min.js create mode 100644 package.json create mode 100755 src/echo.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..04ba039 --- /dev/null +++ b/.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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c8e43e --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules +.DS_Store +.tmp +.sass-cache diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..493798b --- /dev/null +++ b/.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 +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..b8fe41e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - "0.11" + - "0.10" + - "0.8" \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..1219450 --- /dev/null +++ b/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" + ]); + +}; \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..8153d7c --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# Echo [![Build Status](https://travis-ci.org/toddmotto/echo.png)](https://travis-ci.org/toddmotto/echo) + + + +```html +Photo +``` + +## 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 `` tag so the DOM tree is populated when the script runs. + +```html + + + + +``` + +## Configuring Echo +Echo config is super-simple, just add the image that needs to load when visible in a `data-echo` attribute: + +```html +Photo +``` + +## 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 \ No newline at end of file diff --git a/dist/echo.js b/dist/echo.js new file mode 100644 index 0000000..a321967 --- /dev/null +++ b/dist/echo.js @@ -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); \ No newline at end of file diff --git a/dist/echo.min.js b/dist/echo.min.js new file mode 100644 index 0000000..885edf5 --- /dev/null +++ b/dist/echo.min.js @@ -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= 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); \ No newline at end of file