Skip to content

Instantly share code, notes, and snippets.

@eduardo-matos
Last active December 11, 2015 02:18
Show Gist options
  • Save eduardo-matos/4529082 to your computer and use it in GitHub Desktop.
Save eduardo-matos/4529082 to your computer and use it in GitHub Desktop.
Implementação de Lazyload em Dojo Toolkit
http://jsfiddle.net/6Xeen/3/
<div id="tall"></div>
<div><span data-lazyload-original="http://placekitten.com/200/205"></span></div>
<div><span data-lazyload-original="http://placekitten.com/200/210" data-lazyload-alt="Alt da imagem"></span></div>
<div><span data-lazyload-original="http://placekitten.com/200/220"></span></div>
<div><span data-lazyload-original="http://placekitten.com/200/230"></span></div>
<div><span data-lazyload-original="http://placekitten.com/200/240"></span></div>
<div><span data-lazyload-original="http://placekitten.com/200/250"></span></div>
<div><span data-lazyload-original="http://placekitten.com/200/260"></span></div>
<div><span data-lazyload-original="http://placekitten.com/200/270"></span></div>
<div><span data-lazyload-original="http://placekitten.com/200/280"></span></div>
<div><span data-lazyload-original="http://placekitten.com/200/290"></span></div>
<div><span data-lazyload-original="http://placekitten.com/200/300"></span></div>
define('Lazyload',[
'dojo/_base/declare',
'dojo/_base/lang',
'dojo/window',
'dojo/dom-geometry',
'dojo/dom-construct',
'dojo/dom-attr',
'dojo/dom-style',
'dojo/on',
'dojo/topic',
'dojo/NodeList',
'dojo/_base/fx'
], function(declare, lang, win, geometry, domConstruct,
domAttr, domStyle, on, topic, NodeList, fx) {
/**
* @class cf.Lazyload
* Classe responsável por carregar imagens dinamicamente.
*
* Uso minimalista
*
* require([
* 'cf/Lazyload',
* 'dojo/dom'
* ], function(Lazyload, dom) {
* new Lazyload(dom.byId('placeholder'));
* });
*
* Passando algumas opcões a mais...
*
* require([
* 'cf/Lazyload',
* 'dojo/query'
* ], function(Lazyload, query) {
* new Lazyload(query('.placeholder'), {
* sourceParamName: 'data-original',
* altParamName: 'data-alt',
* threshold: 200
* });
* });
*/
var Lazyload = declare(null, {
/**
* @cfg threshold
* Distância mínima que a tela deve estar da imagem para
* que esta seja carregada.
*
* @type {Number}
*/
threshold: 0,
/**
* @cfg sourceParamName
* Nome do atributo do elemento que substitui o
* atributo _src_ da imagem.
*
* @type {String}
*/
sourceParamName: 'data-lazyload-original',
/**
* @cfg altParamName
* Nome do atributo do elemento que substitui o
* atributo _alt_ da imagem. Caso o elemento
* placeholder nao tenha este atributo, a imagem
* não terá _alt_.
*
* @type {String}
*/
altParamName: 'data-lazyload-alt',
/**
* @cfg fx Efeito aplicado a imagem assim que ela e carregada
*
* @type {String}
*/
fx: 'fadeIn',
/**
* @property _elems
* NodeList com os elementos que serão transformados
* em imagem pelo Lazyload
*
* @type {dojo.NodeList}
* @private
*/
_elems: null,
/**
* @constructor
*
* @param {Mixed} node Elementos que serão convertidos em imagens
* pelo lazyload. Pode ser um elemento HTML ou um NodeList
*
* @param {Object} opts
*
* @param {Number} opts.threshold Distância que a tela dele estar do elemento
* antes que ele se transforme em uma imagem de fato
*
* @param {String} opts.sourceParamName Nome do atributo que conterá _src_
* da imagem
*
* @param {String} opts.altParamName Nome do atributo que conterá _alt_
* da imagem
*
* @param {String} opts.fx efeito aplicado à imagem assim que for carregada
*/
constructor: function(node, opts) {
if(!node) {
return false;
} else if(1 === node.nodeType) {
// aparentemente é um HTMLElement. Converter para NodeList
this._elems = new NodeList(node);
} else if(node.every){
// Aparentemente é um NodeList
this._elems = node;
} else {
return false;
}
lang.mixin(this, opts);
var me = this;
on(document, 'scroll', function (evt) {
me._onWindowScroll();
});
},
/**
* @method _onWindowScroll Método executado a cada vez que a tela rola
*
* @private
*/
_onWindowScroll: function() {
var me = this;
var elemsToRemove = [];
if(null !== me._elems) {
me._elems.forEach(function(node, index) {
if(0 >= geometry.position(node).y - win.getBox().h - me.threshold) {
me._loadImage(node);
elemsToRemove.push(index);
}
});
var newElems = new NodeList();
me._elems.map(function(node, index) {
if(elemsToRemove.indexOf(index) < 0) {
newElems.push(node);
}
});
if(newElems.length) {
me._elems = newElems;
} else {
me._elems = null;
}
}
},
/**
* @method _loadImage Método executado cada vez que uma imagem deve ser carregada
*
* @param {HTMLElement} placeholderNode Node que deve se transformar em imagem
*
* @private
*/
_loadImage: function(placeholderNode) {
if(domAttr.has(placeholderNode, this.sourceParamName)) {
var imageSource = domAttr.get(placeholderNode, this.sourceParamName);
var imageNode = domConstruct.toDom('<img src="' + imageSource + '" />');
if(domAttr.has(placeholderNode, this.altParamName)) {
domAttr.set(imageNode, 'alt', domAttr.get(placeholderNode, this.altParamName));
}
if(this.fx) {
switch(this.fx) {
case 'fadeIn':
domStyle.set(imageNode, 'opacity', '0');
var effect = fx.fadeIn({ node: imageNode, duration: 400 });
on(imageNode, 'load', function (evt) {
effect.play();
});
break;
}
}
domConstruct.place(imageNode, placeholderNode, 'replace');
topic.publish('lazyload/load-image', { node: imageNode });
}
}
});
lang.extend(NodeList, {
lazyload: function(opts) {
new Lazyload(this, opts);
return this;
}
});
return Lazyload;
});
require([
'Lazyload',
'dojo/query',
'dojo/domReady!'
], function(Ll, query) {
/*** Outra maneira de usar
new Ll(query('span'), {
threshold: 50
});
*/
query('span').lazyload({
threshold: 200
});
});
#tall { height: 1000px; }
div {margin-bottom: 10px;}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment