Comparing version 0.0.3 to 1.0.0
@@ -1,11 +0,75 @@ | ||
**lozad.js** is written in JavaScript. | ||
# Contributing to lozad.js | ||
:sparkles:First off, thanks for taking the time to contribute!:sparkles: | ||
#Setup | ||
1. [Fork **lozad.js**](https://help.github.com/articles/fork-a-repo) and clone it on your system. | ||
2. Create a new branch out off `master` for your fix/feature. `git checkout new-feature master` | ||
Now, take a moment to be sure your contributions make sense to everyone else. | ||
These are just guidelines, not rules. | ||
Use your best judgment, and feel free to propose changes to this document in a pull request. | ||
#Things to remember | ||
## How can I contribute? | ||
- Do not fix multiple issues in a single commit. Keep them one thing per commit so that they can be picked easily incase only few commits require to be merged. | ||
- Before submitting a patch, rebase your branch on upstream `master` to make life easier for the merger. | ||
- **DO NOT** add the library build (`dist/lozad.min.js`) in your commits. | ||
### Improve documentation | ||
As a user of Lozad.js, you're the perfect candidate to help us improve our documentation. Typo corrections, error fixes, better explanations, more examples, etc. Open issues for things that could be improved. Anything. Even improvements to this document. | ||
### Improve issues | ||
Some issues are created with missing information, not reproducible, or plain invalid. Help make them easier to resolve. Handling issues takes a lot of time that we could rather spend on fixing bugs and adding features. | ||
### Give feedback on issues | ||
We're always looking for more opinions on discussions in the issue tracker. It's a good opportunity to influence the future direction of Lozad.js | ||
## Reporting Issues | ||
- Found a problem? Want a new feature? First of all see if your issue or idea has [already been reported](https://github.com/ApoorvSaxena/lozad.js/issues). | ||
- If don't, just open a [new clear and descriptive issue](https://github.com/ApoorvSaxena/lozad.js/issues/new). | ||
- Use a clear and descriptive title. | ||
- Include as much information as possible: Steps to reproduce the issue, error message, Browser version, operating system, etc. | ||
- The more time you put into an issue, the more we will. | ||
## Submitting pull requests | ||
- Non-trivial changes are often best discussed in an issue first, to prevent you from doing unnecessary work. | ||
- For ambitious tasks, you should try to get your work in front of the community for feedback as soon as possible. Open a pull request as soon as you have done the minimum needed to demonstrate your idea. At this early stage, don't worry about making things perfect, or 100% complete. Add a [WIP] prefix to the title, and describe what you still need to do. This lets reviewers know not to nit-pick small details or point out improvements you already know you need to make. | ||
- New features should be accompanied with tests and documentation. | ||
- Don't include unrelated changes. | ||
- Lint and test before submitting the pull request by running `$ npm test`. | ||
- Make the pull request from a [topic branch](https://github.com/dchelimsky/rspec/wiki/Topic-Branches), not master. | ||
- Use a clear and descriptive title for the pull request and commits. | ||
- Write a convincing description of why we should land your pull request. It's your job to convince us. Answer "why" it's needed and provide use-cases. | ||
- You might be asked to do changes to your pull request. There's never a need to open another pull request. [Just update the existing one.](https://github.com/RichardLitt/docs/blob/master/amending-a-commit-guide.md) | ||
## Code Style | ||
Follow the [xo](https://github.com/sindresorhus/xo) style. | ||
Using two spaces for identation and no [semicolons](http://blog.izs.me/post/2353458699/an-open-letter-to-javascript-leaders-regarding). | ||
## Commit Message Emoji | ||
Every commit is important. | ||
So let's celebrate each and every commit with a corresponding emoji! :smile: | ||
### Which Emoji to Use? :confused: | ||
Commit Type | Emoji | ||
---------- | ------------- | ||
Initial Commit | :tada: `:tada:` | ||
Improve the format/structure of the code | :art: `:art:` | ||
Improving performance | :racehorse: `:racehorse:` | ||
Writing docs | :memo: `:memo:` | ||
Fix a bug | :bug: `:bug:` | ||
Remove code or files | :fire: `:fire:` | ||
Fix CI build | :green_heart: `:green_heart:` | ||
Deal with security | :lock: `:lock:` | ||
Upgrade dependencies | :arrow_up: `:arrow_up:` | ||
Downgrading dependencies | :arrow_down: `:arrow_down:` | ||
Add tests | :umbrella: `:umbrella:` | ||
Improving accessibility | :wheelchair: `:wheelchair:` | ||
Add new features | :sparkles: `:sparkles:` | ||
Refactoring | :package: `:package:` | ||
Other | [Be creative](http://www.emoji-cheat-sheet.com/) | ||
## Scripts | ||
The follow scripts are available when you develop. | ||
- `npm run lint` - Lint the files. | ||
- `npm run build` - Build the package. |
@@ -1,84 +0,80 @@ | ||
/*! lozad.js - v0.0.3 - 2017-09-05 | ||
/*! lozad.js - v0.0.3 - 2017-09-08 | ||
* https://github.com/ApoorvSaxena/lozad.js | ||
* Copyright (c) 2017 Apoorv Saxena; Licensed MIT */ | ||
;(function() { | ||
const _Lozad = function(config) { | ||
this.config = config || {}; | ||
this.config.selector = this.config.selector || '.lozad'; | ||
this.config.rootMargin = this.config.rootMargin || '0px'; | ||
this.config.threshold = this.config.threshold || 0; | ||
this.activate(); | ||
}; | ||
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | ||
typeof define === 'function' && define.amd ? define(factory) : | ||
(global.lozad = factory()); | ||
}(this, (function () { 'use strict'; | ||
_Lozad.prototype.activate = function() { | ||
if (!window.IntersectionObserver) { | ||
loadAll.call(this); | ||
} else { | ||
if (this.observer) { | ||
this.observer.disconnect(); | ||
} | ||
this.observer = new IntersectionObserver(onIntersection.bind(this), this.config); | ||
var elements = getElements.call(this); | ||
for (var i = 0; i < elements.length; i++) { | ||
if (!isLoaded(elements[i])) { | ||
this.observer.observe(elements[i]); | ||
} | ||
} | ||
} | ||
}; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
const getElements = function() { | ||
return document.querySelectorAll(this.config.selector); | ||
}; | ||
var defaultConfig = { | ||
rootMargin: '0px', | ||
threshold: 0, | ||
load: function load(element) { | ||
element.src = element.dataset.src; | ||
} | ||
}; | ||
const loadAll = function() { | ||
var elements = getElements.call(this); | ||
for (var i = 0; i < elements.length; i++) { | ||
if (!isLoaded(elements[i])) { | ||
this.load(elements[i]); | ||
markAsLoaded(elements[i]); | ||
} | ||
} | ||
}; | ||
function markAsLoaded(element) { | ||
element.dataset.loaded = true; | ||
} | ||
_Lozad.prototype.load = function(el) { | ||
el.src = el.dataset.src; | ||
}; | ||
var isLoaded = function isLoaded(element) { | ||
return element.dataset.loaded === 'true'; | ||
}; | ||
const markAsLoaded = function(el) { | ||
el.dataset.loaded = true; | ||
}; | ||
var onIntersection = function onIntersection(load) { | ||
return function (entries, observer) { | ||
entries.forEach(function (entry) { | ||
if (entry.intersectionRatio > 0) { | ||
observer.unobserve(entry.target); | ||
load(entry.target); | ||
markAsLoaded(entry.target); | ||
} | ||
}); | ||
}; | ||
}; | ||
const onIntersection = function(entries) { | ||
for (var i = 0; i < entries.length; i++) { | ||
if (entries[i].intersectionRatio > 0) { | ||
this.observer.unobserve(entries[i].target); | ||
this.load(entries[i].target); | ||
markAsLoaded(entries[i].target); | ||
} | ||
} | ||
}; | ||
var lozad = function () { | ||
var selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '.lozad'; | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
const isLoaded = function(el) { | ||
return (el.dataset.loaded === "true"); | ||
}; | ||
var _defaultConfig$option = _extends({}, defaultConfig, options), | ||
rootMargin = _defaultConfig$option.rootMargin, | ||
threshold = _defaultConfig$option.threshold, | ||
load = _defaultConfig$option.load; | ||
// open to the world. | ||
// commonjs | ||
if (typeof exports === 'object') { | ||
module.exports = _Lozad; | ||
} | ||
// AMD module | ||
else if (typeof define === 'function' && define.amd) { | ||
define('Lozad', function() { | ||
return _Lozad; | ||
var observer = new IntersectionObserver(onIntersection(load), { | ||
rootMargin: rootMargin, | ||
threshold: threshold | ||
}); | ||
return { | ||
observe: function observe() { | ||
var elements = [].filter.call(document.querySelectorAll(selector), function (element) { | ||
return !isLoaded(element); | ||
}); | ||
if (!window.IntersectionObserver) { | ||
elements.forEach(function (element) { | ||
load(element); | ||
markAsLoaded(element); | ||
}); | ||
return; | ||
} | ||
elements.forEach(function (element) { | ||
observer.observe(element); | ||
}); | ||
} | ||
// Browser global | ||
else { | ||
window.Lozad = _Lozad; | ||
} | ||
}; | ||
}; | ||
})(); | ||
return lozad; | ||
}))); |
@@ -1,5 +0,4 @@ | ||
/*! lozad.js - v0.0.3 - 2017-09-05 | ||
/*! lozad.js - v0.0.3 - 2017-09-08 | ||
* https://github.com/ApoorvSaxena/lozad.js | ||
* Copyright (c) 2017 Apoorv Saxena; Licensed MIT */ | ||
!function(){const a=function(a){this.config=a||{},this.config.selector=this.config.selector||".lozad",this.config.rootMargin=this.config.rootMargin||"0px",this.config.threshold=this.config.threshold||0,this.activate()};a.prototype.activate=function(){if(window.IntersectionObserver){this.observer&&this.observer.disconnect(),this.observer=new IntersectionObserver(e.bind(this),this.config);for(var a=b.call(this),d=0;d<a.length;d++)f(a[d])||this.observer.observe(a[d])}else c.call(this)};const b=function(){return document.querySelectorAll(this.config.selector)},c=function(){for(var a=b.call(this),c=0;c<a.length;c++)f(a[c])||(this.load(a[c]),d(a[c]))};a.prototype.load=function(a){a.src=a.dataset.src};const d=function(a){a.dataset.loaded=!0},e=function(a){for(var b=0;b<a.length;b++)a[b].intersectionRatio>0&&(this.observer.unobserve(a[b].target),this.load(a[b].target),d(a[b].target))},f=function(a){return"true"===a.dataset.loaded};"object"==typeof exports?module.exports=a:"function"==typeof define&&define.amd?define("Lozad",function(){return a}):window.Lozad=a}(); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.lozad=e()}(this,function(){"use strict";function t(t){t.dataset.loaded=!0}var e=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(t[o]=n[o])}return t},n={rootMargin:"0px",threshold:0,load:function(t){t.src=t.dataset.src}},o=function(t){return"true"===t.dataset.loaded},r=function(e){return function(n,o){n.forEach(function(n){n.intersectionRatio>0&&(o.unobserve(n.target),e(n.target),t(n.target))})}};return function(){var i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:".lozad",a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},c=e({},n,a),u=c.rootMargin,f=c.threshold,d=c.load,s=new IntersectionObserver(r(d),{rootMargin:u,threshold:f});return{observe:function(){var e=[].filter.call(document.querySelectorAll(i),function(t){return!o(t)});window.IntersectionObserver?e.forEach(function(t){s.observe(t)}):e.forEach(function(e){d(e),t(e)})}}}}); |
@@ -5,4 +5,9 @@ { | ||
"description": "A light-weight JS library to lazy load any HTML element such as images, ads, videos etc.", | ||
"version": "0.0.3", | ||
"version": "1.0.0", | ||
"homepage": "https://github.com/ApoorvSaxena/lozad.js", | ||
"scripts": { | ||
"build": "node build.js", | ||
"prelint": "prettier --single-quote --no-semi --no-bracket-spacing --trailing-comma none --write \"lib/**/*.js\" --write build.js --write", | ||
"lint": "xo --fix src/*.js build.js" | ||
}, | ||
"author": { | ||
@@ -39,7 +44,19 @@ "name": "Apoorv Saxena", | ||
"devDependencies": { | ||
"grunt-contrib-concat": "~0.5.1", | ||
"grunt": "~0.4.5", | ||
"grunt-contrib-jshint": "^0.11.0", | ||
"grunt-contrib-uglify": "~0.8.0" | ||
"babel-core": "^6.26.0", | ||
"babel-preset-env": "^1.6.0", | ||
"babel-preset-stage-0": "^6.24.1", | ||
"prettier": "^1.6.1", | ||
"rollup": "^0.49.2", | ||
"rollup-plugin-babel": "^3.0.2", | ||
"rollup-plugin-filesize": "^1.4.2", | ||
"rollup-plugin-license": "^0.5.0", | ||
"rollup-plugin-uglify": "^2.0.1" | ||
}, | ||
"xo": { | ||
"envs": [ | ||
"browser" | ||
], | ||
"semicolon": false, | ||
"space": true | ||
} | ||
} |
@@ -1,26 +0,34 @@ | ||
Lozad [![npm version](https://badge.fury.io/js/lozad.svg)](https://badge.fury.io/js/lozad) | ||
===== | ||
*Advanced performant Lazy Loader using Intersection Observer API* | ||
*** | ||
# Lozad.js [![npm version](https://badge.fury.io/js/lozad.svg)](https://badge.fury.io/js/lozad) | ||
> Highly performant, light ~0.5kb and configurable lazy loader in pure JS with no dependencies for images, iframes and more, using IntersectionObserver API | ||
![lozad.js lazy loading javascript library](./banner/lozad-banner.png "lozad.js lazy loading javascript library") | ||
- is a light-weight library, *just **569 bytes*** minified & gzipped, | ||
**Lozad.js**: | ||
- lazy loads elements performantly using pure JavaScript, | ||
- is a light-weight library, *just **535 bytes*** minified & gzipped, | ||
- has NO DEPENDENCIES :) | ||
- lazy loads elements performantly using pure JavaScript. | ||
- allows lazy loading of dynamically added elements as well. | ||
It is written with an aim to lazy load images, ads, videos or any other element using the recently added [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) with tremendous performance benefits. | ||
It is written with an aim to lazy load images, iframes, ads, videos or any other element using the recently added [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) with tremendous performance benefits. | ||
Yet another Lazy Loading JavaScript library, why? | ||
----- | ||
Existing lazy loading libraries hook up the scroll event or use a periodic timer and call getBoundingClientRect() on elements that need to be lazy loaded. This approach, however, is painfully slow as each call to getBoundingClientRect() forces the browser to re-layout the entire page and will introduce considerable jank to your website. | ||
## Table of Contents | ||
- [Demo](https://apoorv.pro/lozad.js/demo/) | ||
- [Background](#yet-another-lazy-loading-javascript-library-why) | ||
- [Install](#install) | ||
- [Usage](#usage) | ||
- [Browser Support](#browser-support) | ||
- [FAQs](#faqs) | ||
- [Contribute](#contribute) | ||
- [Changelog](#changelog) | ||
- [License](#license) | ||
## Yet another Lazy Loading JavaScript library, why? | ||
Existing lazy loading libraries hook up to the scroll event or use a periodic timer and call `getBoundingClientRect()` on elements that need to be lazy loaded. This approach, however, is painfully slow as each call to `getBoundingClientRect()` forces the browser to re-layout the entire page and will introduce considerable jank to your website. | ||
Making this more efficient and performant is what [IntersectionObserver](https://developers.google.com/web/updates/2016/04/intersectionobserver) is designed for, and it’s landed in Chrome 51. IntersectionObservers let you know when an observed element enters or exits the browser’s viewport. | ||
[Demo](https://apoorv.pro/lozad.js/demo/index.html) | ||
----- | ||
## Install | ||
Get Started | ||
----- | ||
Get the library using one of the following ways: | ||
@@ -54,6 +62,5 @@ | ||
**Note**: **lozad.js** supports AMD and commonJS module pattern out of the box. | ||
**Note**: `lozad.js` supports AMD and commonJS module pattern out of the box. | ||
Usage | ||
----- | ||
## Usage | ||
@@ -67,11 +74,12 @@ In HTML, add an identifier to the element (default selector identified is `lozad` class): | ||
```js | ||
new Lozad(); // lazy loads images with selector as '.lozad' | ||
const observer = lozad(); // lazy loads elements with default selector as '.lozad' | ||
observer.observe(); | ||
``` | ||
or with custom options: | ||
```js | ||
new Lozad({ | ||
selector: '.lozad', // for identification of images to lazy load | ||
const observer = lozad('.lozad', { | ||
rootMargin: '10px 0px', // syntax similar to that of CSS Margin | ||
threshold: 0.1 // ratio of image convergence | ||
}) | ||
threshold: 0.1 // ratio of element convergence | ||
}); | ||
observer.observe(); | ||
``` | ||
@@ -85,27 +93,31 @@ Reference: | ||
```js | ||
var lozad = new Lozad(); | ||
lozad('.lozad', { | ||
load: function(el) { | ||
console.log('loading element'); | ||
lozad.load = function(el) { | ||
console.log('loading element'); | ||
// Custom implementation to load an element | ||
// e.g. el.src = el.dataset.src; | ||
} | ||
}); | ||
``` | ||
// Custom implementation to load an element | ||
// e.g. el.src = el.dataset.src; | ||
} | ||
``` | ||
If you want to lazy load dynamically added images: | ||
If you want to lazy load dynamically added elements: | ||
```js | ||
var lozad = new Lozad(); | ||
const observer = lozad(); | ||
observer.observe(); | ||
// ... code to dynamically add elements | ||
lozad.activate(); // observes newly added elements as well | ||
observer.observe(); // observes newly added elements as well | ||
``` | ||
## Browser Support | ||
Browser Support | ||
----- | ||
Available in [latest browsers](http://caniuse.com/#feat=intersectionobserver). If browser support is not available, then make use of this [polyfill](https://www.npmjs.com/package/intersection-observer). | ||
Contributing | ||
----- | ||
## FAQs | ||
Checkout the [FAQ Wiki](https://github.com/ApoorvSaxena/lozad.js/wiki/Frequently-Asked-Questions) for some common gotchas to be aware of while using **lozad.js** | ||
## Contribute | ||
Interested in contributing features and fixes? | ||
@@ -115,11 +127,8 @@ | ||
Changelog | ||
----- | ||
## Changelog | ||
See the [Changelog](https://github.com/ApoorvSaxena/lozad.js/wiki/Changelog) | ||
License | ||
----- | ||
## License | ||
Copyright (c) 2017 Apoorv Saxena, https://apoorv.pro | ||
Licensed under the [MIT license](http://opensource.org/licenses/MIT). | ||
[MIT](LICENSE) © [Apoorv Saxena](https://apoorv.pro) |
113
src/lozad.js
@@ -1,80 +0,53 @@ | ||
;(function() { | ||
const defaultConfig = { | ||
rootMargin: '0px', | ||
threshold: 0, | ||
load(element) { | ||
element.src = element.dataset.src | ||
} | ||
} | ||
const _Lozad = function(config) { | ||
this.config = config || {}; | ||
this.config.selector = this.config.selector || '.lozad'; | ||
this.config.rootMargin = this.config.rootMargin || '0px'; | ||
this.config.threshold = this.config.threshold || 0; | ||
this.activate(); | ||
}; | ||
function markAsLoaded(element) { | ||
element.dataset.loaded = true | ||
} | ||
_Lozad.prototype.activate = function() { | ||
if (!window.IntersectionObserver) { | ||
loadAll.call(this); | ||
} else { | ||
if (this.observer) { | ||
this.observer.disconnect(); | ||
} | ||
this.observer = new IntersectionObserver(onIntersection.bind(this), this.config); | ||
var elements = getElements.call(this); | ||
for (var i = 0; i < elements.length; i++) { | ||
if (!isLoaded(elements[i])) { | ||
this.observer.observe(elements[i]); | ||
} | ||
} | ||
} | ||
}; | ||
const isLoaded = element => element.dataset.loaded === 'true' | ||
const getElements = function() { | ||
return document.querySelectorAll(this.config.selector); | ||
}; | ||
const onIntersection = load => (entries, observer) => { | ||
entries.forEach(entry => { | ||
if (entry.intersectionRatio > 0) { | ||
observer.unobserve(entry.target) | ||
load(entry.target) | ||
markAsLoaded(entry.target) | ||
} | ||
}) | ||
} | ||
const loadAll = function() { | ||
var elements = getElements.call(this); | ||
for (var i = 0; i < elements.length; i++) { | ||
if (!isLoaded(elements[i])) { | ||
this.load(elements[i]); | ||
markAsLoaded(elements[i]); | ||
} | ||
} | ||
}; | ||
export default function (selector = '.lozad', options = {}) { | ||
const {rootMargin, threshold, load} = {...defaultConfig, ...options} | ||
_Lozad.prototype.load = function(el) { | ||
el.src = el.dataset.src; | ||
}; | ||
const observer = new IntersectionObserver(onIntersection(load), { | ||
rootMargin, | ||
threshold | ||
}) | ||
const markAsLoaded = function(el) { | ||
el.dataset.loaded = true; | ||
}; | ||
return { | ||
observe() { | ||
const elements = [].filter.call(document.querySelectorAll(selector), | ||
element => !isLoaded(element)) | ||
const onIntersection = function(entries) { | ||
for (var i = 0; i < entries.length; i++) { | ||
if (entries[i].intersectionRatio > 0) { | ||
this.observer.unobserve(entries[i].target); | ||
this.load(entries[i].target); | ||
markAsLoaded(entries[i].target); | ||
} | ||
} | ||
}; | ||
if (!window.IntersectionObserver) { | ||
elements | ||
.forEach(element => { | ||
load(element) | ||
markAsLoaded(element) | ||
}) | ||
const isLoaded = function(el) { | ||
return (el.dataset.loaded === "true"); | ||
}; | ||
return | ||
} | ||
// open to the world. | ||
// commonjs | ||
if (typeof exports === 'object') { | ||
module.exports = _Lozad; | ||
elements.forEach(element => { | ||
observer.observe(element) | ||
}) | ||
} | ||
// AMD module | ||
else if (typeof define === 'function' && define.amd) { | ||
define('Lozad', function() { | ||
return _Lozad; | ||
}); | ||
} | ||
// Browser global | ||
else { | ||
window.Lozad = _Lozad; | ||
} | ||
})(); | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
704228
35
0
130
0
9
1735