toddmotto / echo Goto Github PK
View Code? Open in Web Editor NEWLazy-loading images with data-* attributes
Home Page: http://toddmotto.com/labs/echo
Lazy-loading images with data-* attributes
Home Page: http://toddmotto.com/labs/echo
I find that on line 13 you should loop over the store incrementally instead.
Better UX when loading (heavy) images, because it will (at least try) to load images in a logical order. This because you are scrolling a webpage from the top to the bottom.
Like this:
for (var i = 0, l = store.length; i < l; i++) {
//...
}
Suppose you have a div
with a given size, position:absolute
and overflow: scroll
. It would be nice if echo would work regardless. Currently it does not because scrolling in the div
does not trigger scroll
of window
. At least in Chrome 31.
window.onscroll fires a lot during scrolling. There should really be some functiona call throttling, e.g., http://documentcloud.github.io/underscore/#throttle
When the element is removed from the DOM, in IE 8 and 9, the call getBoundingClientRect()
break the code.
I did this:
var inView = function (element, view) {
// needs `try catch` because in IE < 10, when the element
// was removed from DOM the getBoundingClientRect() call
// break execution
try {
var box = element.getBoundingClientRect();
return (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b);
} catch(e) {
return false;
}
};
I'm trying to lazy load images from a remote server. I first tried Echo.js using just raw JavaScript and HTML just like this:
<img src="imgs/ionic.png" data-echo="http://somexxhost.org:3002/images/thiscat.jpg" />
It worked as expected (and was fun btw)!
But when I used Echo.js with AngularJS, it doesn't load the last few images. Sometimes it doens't load all the images.
<ion-item ng-repeat="cat in cats">
<img src="img/ionic.png" data-echo="{{cat.imagePath}}" />
</ion-item>
I used Firebug and I saw that src='img/ionic.png'
hasn't been replaced into src="http://somexxhost.org:3002/images/thiscat.jpg"
and data-echo
is still there in the DOM for the images that haven't loaded yet.
The probable reason is that AngularJS data-echo doesn't work right with AngularJS just like reguar src
doesn't work with Angular's {{hash}}
which is why ng-src
was created. I might be wrong but it would be nice to get some explanations, suggestions and possible solutions.
Hi,
I saw this project and it seems that it uses getBoundingClientRect for checking the current visible area but it triggers a repaint, which in a large scale app this won't work very well.
Check out http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html
It seems that after calling render() scrolling no longer triggers new lazyloads to happen. Note: this is being used w/ a grid layout (that can be filtered) but that is also long and is scrolled.
Hi,
Does the plugin supports spinning animation effect instead of lazy loading the image.
since we wanted the plugin to support animation instead of loading the image
I would use it to preload many images contained in a div with "display:none"
but when I load the page it downloaded all my images directly
it possible to use with "diplay none" ?
Try: bower info echo.js
Right now, it appears that the images above the fold (top of the body to the bottom of the view port will load. Even if htey are not visible.
Say you have a very long page with 100 images. And the user is taken to the page with a link with a hash that links to the bottom most image on the page: i.e
Echo currently loads all images above the ones on the bottom of the page. One fix could be to check to see if the image overlaps the view port. A change to the _inView function like this works well:
var _inView = function (element) {
var coords = element.getBoundingClientRect();
var win = {
left: 0 - offset,
top: 0 - offset,
bottom: (window.innerHeight || document.documentElement.clientHeight) + offset,
right: (window.innerWidth || document.documentElement.clientWidth) + offset
}
return (coords.right >= win.left && coords.bottom >= win.top &&
coords.left <= win.right && coords.top <= win.bottom);
};
I've created a jsfiddle with a working example: http://jsfiddle.net/VxrLe/1/
Click the "Go To Bottom" link, then scroll up on the page to see the effect. I've used a long throttle value of 500 to make the delayed loading more evident.
If a user scrolls down to a page that will work but what if he jumps to a point of page by clicking a link to an anchor or some other ways? All the images above that point will be loaded as well. This spoils lazy loading.
You should consider if image will be actually in viewport after lazy load, to load it. Easy to say, hard to make :)
Hi All
I wanted to start an open discussion about future improvements to echo, I am looking to do some serious work on the library to clear the backlog of issues and potentially look at how the library can start to work with the new HTML picture element.
Any ideas for improvements would be welcome and this post seems like a good place to start. Aside from that I would love more people to be contributing so also reply if you think you could help.
Jonathan
<img src="css/img/preloader.gif" alt data-echo="{{item.image}}">
I want to output a javascript object property which points to an img to be loaded by echo.js data-echo but it is failing. I am not exprienced enough to understand how to output the actual string instead of the javascript expression.
Is there any direction you could point me to in order to make this work with angular? I would appreciate it because I like the library a lot.
Thanks for your time.
#29 was closed, it was never merged in the 1.4 version. Things have obviously changed significantly since then, but this plugin still does not support scrolling in an element other than window.
I tried to use the ground work laid in #29 to modify the current version but didn't succeed.
Is this something that can be done easier now with the current version?
Travis is running npm test
with nothing in your package.json, let alone any tests.
I have add data-echo
to all my images but most of the time just the first image is shown while the other still show the loader.
This is my html:
<div class="image">
<img src="img/loader-img.gif" data-echo="img/example.jpg" alt="title">
</div>
and this is my code:
echo.init({
offset: 100,
throttle: 250,
unload: false,
callback: function (element, op) {
$(element).parent().closest('div').addClass('imgLiquidFill imgLiquid');
$(".imgLiquidFill").imgLiquid();
}
});
the callback are called just once, so only the first element will add the imgLiquid class.
How can I solve?
Is is possible?
Tried changing the line number 19
self.style = "background-image: url('"+self.getAttribute('data-echo')+"')";
but it gives me this error:
TypeError: Attempted to assign to readonly property
OSX 10.8.5 and Safari 6.1.1
Thank you for the very nice library!
I want to add an option that can change the target selector from the outside of the library.
The following is an example of the API.
echo.init({
selector: 'img[data-echo], iframe[data-echo], [echo-background]'
});
How do you like it?
for example If this had property 'replaceBrokenImagesWith' I would set any default image to show in place of broken images.
it could be also callback function that is being invoked every time when error is occurred passing by broken image name and sets callback result into images' src attribute.
what about ajax support?
Thank you for the plugin. I works fine! At the moment I use it to pull images and set a class for them with the way like this:
echo.init({
offset: 100,
throttle: 1,
unload: false,
callback: function (element, op) {
element.className = "fade-in";
}
});
I would also like to set a special class for some tags which come into view when scrolling (a kind of inView feature). Is there a correct way to do this?
if some elements not need lazy-load,what should I do?
Perhaps we can add an option to check whether an element is visible:
The simplest:
var isVisible = element.offsetWidth > 0 || element.offsetHeight > 0;
Or if we want to go full crazy: http://useallfive.com/thoughts/javascript-tool-detect-if-a-dom-element-is-truly-visible/
If I had any collection of BB views and each has own image then how can I init the echo for image for each view only?
How to use in anguarjs?
What about when the image has been cached by the browser? Will it bypass this and fetch it again from the server?
Is there a way to do a callback after the image is rendered?
Hi, I have one question.
In this line: https://github.com/toddmotto/echo/blob/master/dist/echo.js#L8
why not do module.exports = factory(root)
?
By default , I will get a function , I should do call it to get the object.
this is by design?
Thanks!
When a list of images inside a scrollable div, only images at the top would be loaded. structure like below:
<ul class='photo--list' style='height: 200px;'>
<li class='photo' style='height: 100px;' id='a'>
<img data-echo='some url'/>
</li>
<li class='photo' style='height: 100px;' id='b'>
<img data-echo='some url'/>
</li>
<li class='photo' style='height: 100px;' id='c'>
<img data-echo='some url'/>
</li>
<li class='photo' style='height: 100px;' id='d'>
<img data-echo='some url'/>
</li>
<li class='photo' style='height: 100px;' id='e'>
<img data-echo='some url'/>
</li>
<li class='photo' style='height: 100px;' id='f'>
<img data-echo='some url'/>
</li>
</ul>
In this circumstance, only photo a
and photo b
would be loaded. Photo c, d, e, f
would not be loaded, for the reason that the root
variable inside Echo.js
is setted to be global
(which is window
mostly).
To solve this problem, the root
variable need to be configurable. Modification is listed below:
echo.init = function (opts) {
opts = opts || {};
// modification
root = opts.viewport || this || (0,eval)('this')
// original codes
};
ethonchan
2015-04-01
you must include license text for MIT license
Is there any option available to use with retina.js?
When visitor scroll down web page to bottom,
call Ajax to request more images and add to page
Echo can't lazy load for these new images
The images beyond the viewport were not suppose to be 'unloaded'? I was thinking that the attribute src of those images would be removed.
I'm not sure if i understood this functionality.
Thank you :)
But the latest release is 1.7.0.
Is it possible to setup echo.js to apply different options per element within one page? For instance I have a small carousel near the top of the page and a slider near the bottom of the page that is the width of the entire page. I want to apply different echo options to these separate features. Is this possible and if so how do I execute? Thanks for any suggestions!
sometimes the images are loaded sometimes didn't,,,
The big problem with this is that the images won't show if there is no javascript. It would be better to leave the original img src and change it with javascript to the loading image...
Great library.
Though I was having issue with mobile devices in trying to get the correct view port size. Made slight modification below to make it work just for use in mobile sites. Please let me know what you think.
_inView
@param {Element} element Image element
@returns {Boolean} Is element in viewport
*/
var _inView = function (element) {
var coords = element.getBoundingClientRect();
return ((coords.top >= 0 && coords.left >= 0 && coords.top) <= (_returnHeight()) + offset);
};
@returns height of viewport
*/
var _returnHeight = function() {
return Math.min(
document.body.scrollHeight, document.documentElement.scrollHeight,
document.body.offsetHeight, document.documentElement.offsetHeight,
document.body.clientHeight, document.documentElement.clientHeight,
window.innerHeight, screen.height
);
}
I'm using the popular Masonry plugin: http://masonry.desandro.com/ and Zepto
Echo doesn't seem to trigger on scroll, does it have anything to do with the fact Masonry positions the images absolutely?
Can the owner do the following? Needs to be done by the owner and not a user/fan.
Add this repo to http://bower.io
Make a pull request to CDNjs.com so we can use this from a CDN
I have some images that are already on the viewport. But it does not lazy load them, it loads all the images below the viewport when I scroll.
These images that were originally in the viewport are left as it is. Any pointers? Thanks!
If echo.js meet TAB ,It'll can't work unless we rolling screen
I've been using this on my website and people are complaining about the order that the images are loaded if they scroll too fast (or before the images are loaded) by them.
If I open the gallery and scroll down before the first images are loaded, the script loads them from last to first. Is there a way to avoid that and let it load on the default order?
example: http://ihateflash.net/set/wobble-4-finnest-ears-apresentam-ney-faustini
Thanks!
I'm trying to load the script with RequiJS and I get and error "TypeError: root.removeEventListener is not a function".
My config.js
file:
require.config({
paths: {
echo: '../../dist/lib/echo'
},
deps: ['modules/app']
});
Then in app.js
:
define(function(require) {
var echo = require('echo');
echo.init({
offset: 100,
throttle: 250,
unload: false,
callback: function(el, op) {
el.style.opacity = 1;
}
});
}
If you lazy load images outside of the browser view, then upsize the browse so they become in view the images never load. You have to trigger a scroll event.
Chrome
Version 31.0.1650.57
I'm working on such case, rendering item views of a listview asynchronously. echo
was initialized as soon as DOMContentLoaded, and then item views were rendered one by one.
It turns out that scroll event handler may be detached if length of document.querySelectorAll('img[data-echo], [data-echo-background]')
is 0.
It would be better that the scroll event handler was kept as it is. Because the nodes
in the method render is not cached at all. Every time the render method is called, the nodes
can be updated. While nodes.length > 0
, scroll handler can be called.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.