I have a problem with my dynamic integration of Lazysizes plugin.
The fact is when I load the page (cache disable), all images of the src are loaded with the content.
After this, responsives images are lazy-loaded like I want.
My reflection :
I replace src attribute with a small image - but browser keeps to load original images before change src with this small image.
all images aren't display in the viewport when the page load because I use the padding ratio trick for each of them.
I tried to move my script in the header of the page, but nothing change.
Here my jquery script at the bottom of the page :
//lazy init
window.lazySizesConfig = window.lazySizesConfig || {};
lazySizesConfig.loadMode = 2;
lazySizesConfig.preloadAfterLoad = false;
$('img').addClass('lazyload');
$("img.lazyload").each(function() {
var src = $(this).attr('src').replace(/\.jpg$/i, "");
$(this).attr("data-sizes","auto");
$(this).attr("data-srcset",
src + '-240.jpg 240w,' +
src + '-360.jpg 360w,' +
src + '-480.jpg 480w, ' +
src + '-720.jpg 720w,' +
src + '-768.jpg 768w,' +
src + '-960.jpg 960w,' +
src + '-1280.jpg 1280w'
);
$(this).attr(
"src",
"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
);
});
I would like only responsive img is load when it is in the viewport.
any idea about my issue ?
thanks
The issue that you're having is caused by the fact, that you're using JavaScript, to set the data-sizes and data-srcset attributes.
lazySizes script expects you to specify all of that in your HTML output.
You have to make sure that jQuery will be loaded, and your script will be executed before lazysizes.js.
I can't guarantee for any of my advice below to be useful, because this script is not intended to be used like that. Still, if you really want to get it to work with jQuery script from your question, consider the following:
Remove async attribute from lazysizes <script> tag.
Set lazySizesConfig.preloadAfterLoad = true;
Run your script right after jQuery is loaded, doesn't matter where you put the script, just make sure it's executed before lazySizes and on $(document).ready().
Only if all above is done, the lazySizes should lazyload the images as expected.
You first need to specify data- atributtes.
Load HTML
Load jQuery and lazysizes.js
Get all data- and save in variable
Handle with it
I don't know if lazysizes.js have inside script some document ready function or some DOM change sniffer but I think you need a different approach.
Related
A lot of the time we load an image via jQuery in the background before appending it to the DOM like so
var image = $('<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=350%C3%97150&w=350&h=150" />');
image.load(function(){
//the image is now loaded and can be appended
});
Although stated in the docs that there are caveats to this method (that ultimately it is not 100% reliable), it is a good method for what we need.
Taking this principle, I want to load an iframe and wait for it to be loaded before proceeding
//method does not fire
var iframe = $('<iframe src="http://example.com"></iframe>');
iframe.load(function(){
//the iframe is now loaded and can be appended
});
However, it appears to be so that the iframe needs to be in the DOM before that load event is called, in contrast to the loading of the image:
//method now fires
var iframe = $('<iframe src="http://example.com"></iframe>');
$("body").append(iframe);
iframe.load(function(){
//the iframe is now loaded and can be appended
});
What is the reason for this? I cannot seem to find it documented anywhere. I know in practice it'd be easy enough to set the style to display none then manipulate it once it's loaded, but I'm more interested in the why as opposed to the how. Thanks!
I have a classified style website with 50-100 images per page all loading from different sources at once. Sometimes I get a 404 and I'm trying to handle that.
On each element containing images I have this script:
$el.find('img').one('error', function() {
console.log('broken image detected');
// Replace broken image with something else
}).each(function() {
if(this.complete || $(this).height() > 0){
$(this).load();
}
});
But it seems to fire at random, not picking up all 404 load errors - especially at the beginning of the page where literally none of the 404s are detected. Towards the end of the page it looks a bit better.
What's going on?
I should add, that this piece of JavaScript is not initialised BEFORE the entire DOM has finished loading, but I was under the impression that the .each part would cater for this?
Another idea would be to insert an inline load error detector:
<img src="http://example.com/image.jpg" onerror="window.errorHandler(this);">
But since my JavaScript is modular in design I would prefer to avoid this.
--- EDIT ---
I have solved this problem by inserting an inline script on the onerror handler. It's not super elegant, but it works because the listener is inserted at the same time as the src attribute. Also it is not dependent on jQuery.
I have done a slight work around in my front-end code to cater for this, by exposing a function to window.
All listeners to handle load or error events must be set BEFORE src property of img is setted.
You may implement lazy loading (i.e. insert <img> paths in a data attribute, put a fake pixel in the src attribute, and load the real images on DOM load with jQuery or JavaScript). You then shouldn't face any timing problems.
HTML:
<div id="gallery">
<img id="img1"
src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEAAAAALAAAAAABAAEAAAI="
data-src="imagethatgives404.gif"
width="200" height="200">
<img id="img2"
src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEAAAAALAAAAAABAAEAAAI="
data-src="http://static.jsbin.com/images/dave.min.svg"
width="200" height="200">
</div>
JS:
$(document).ready(function(){
var $el = $('#gallery');
$el.find('[data-src]')
.one('error', function(e) {
console.log(e.target.id + ' is broken');
// Replace broken image with something else
})
.each(function(index,element){
element.src = $(element).data('src');
});
});
The width and height on the <img> tags are used to show how dimensions are preserved.
Example here.
I want to synchronize web site like when page load first it will load content then images then flash content then another content.
Like i have seen the same at http://gmailblog.blogspot.com/ [ see how images load ]
Is there any way to achieve? Any link or source code would be appreciated.
I seen the web site. This is the same thing that happens with bing. How to do this ?
In the core HTML code give the <img src="loading.gif" id="1"/> or whatever element you want.
When the Core HTML is done, before the </body> tag, use javascript to change the
attributes values (for eg. "src" attribute of the img element). Remeber the javascript need to be written at the end of the HTML before closing the body tag. The browser will load the
contents accordingly in sequence. This can be used to achieve priority based loading of HTML components.
You can synchronize loading of all elements on your page by controlling it using JS. For ex: one strategy to load images after content would be:
a) In your html, instead of in the src attribute, specify the image location in another attribute, say 'isrc'.
b) Inside your onload callback (assumes you're using jQuery):
var loadCounter = 0;
$('img').each(function() {
if($(this).attr('isrc')) {
this.onload = function() {
loadCounter++;
if($('img[isrc]').length == loadCounter) {
// .. proceed to loading other stuff like flash etc..
}
}
$(this).attr('src', $(this).attr('isrc')); // load the image
}
});
I'm a creating a loading screen for website I am making. The website loads many images, scripts, etc. The HTML and CSS part is great, but I need a way to guarantee that the "loading..." image will be loaded before anything else.
I'm using jQuery, and everything is initiated within $(function () { ... });. I imagine that the code for this would need to be called before/outside that block, and the code to remove the loading screen will be called at the very end of that block. Currently, the loading image is set as a DIV background, which is the way I prefer it. However, if it's completely necessary, I will settle for an IMG tag.
Update: (solution)
I was able to answer my own question by using a combination of Robin and Vlad's responses. Both were very good, and excellent answers, however the problem is that they were aimed to load an image before another image, rather than load an image before anything else. (CSS, JS, etc...)
Here's the dirty version of what I came up with:
var files = [new Image(), document.createElement('link'), document.createElement('script')];
files[0].setAttribute('src', 'images/loading.gif');
files[1].setAttribute('rel', 'stylesheet');
files[1].setAttribute('type', 'text/css');
files[1].setAttribute('href', 'test.css');
files[2].setAttribute('type', 'text/javascript');
files[2].setAttribute('src', 'js/jquery-1.5.1.min.js');
window.onload = function (e) {
document.getElementsByTagName('head')[0].appendChild(files[1]);
document.getElementsByTagName('head')[0].appendChild(files[2]);
}
Taking a look at the load sequence on the network tab of Chrome's developer console shows that 'loading.gif' is loaded first, then 4 dummy images, then 'test.css', and then 'jquery.1.5.1.min.js'. The CSS and JS files don't begin to load, until they've been inserted into the head tag. This is exactly what I want.
I'm predicting that I may begin to have some problems, however, when I begin to load a list of files. Chrome reports that sometimes the JS file is loaded first, but the majority of the time the CSS file is loaded first. This isn't a problem, except when I begin to add files to load, I will need to ensure that jQuery is loaded before a script file that uses jQuery.
If anyone has a solution for this, or a way to detect when the CSS/JS files are finished loading, using this method, then please comment. Though, I'm not sure that it's going to be a problem yet. I may need to ask a new question in the future about this, if I start to run into problems.
Thank you to every who has helped with this issue.
Update: (glitch fix)
I ended up running into a lot of problem with this method, because the script files were being loaded asynchronously. If I would clear the browser cache, and then load the page, it would finish loading my jquery dependent files first. Then if I refreshed the page, it would work, because jquery was loaded from cache. I solved this by setting up an array of files to load, then putting the load script into a function. Then I would step through each array item using this code:
element.onload = function() {
++i; _step();
}
element.onreadystatechange = function() {
if (("loaded" === element.readyState || "complete" === element.readyState)) { ++i; _step(); }
}
You can reuse resource prealoding browser support.
I'm not sure it works across all browsers but in my case this approach helps me to load images first. Also it allows to define concrete images so UI specific could be skipped
First define in header what resource you want to preload and define resource priority
<link rel="preload" href="link-to-image" as="image">
or
<link rel="preload" href="link-to-image">
Second line allow to increase loading priority across all object types (scripts / images / styles). First line - only through images.
Then define in body link to image as usual:
<img src="link-to-image" alt="">
Here is my working example
https://jsfiddle.net/vadimb/05scfL58/
As long as the "loading..." image is positioned before any other html elements, it should load first. This of course depends on the size of the image. You could put the loading div right after the tag and position it using 'position:absolute'.
Regarding the code to remove the loading screen, one method is to do the following.
Put all the images, scripts that need to be loaded in a hidden div (display: none)
Set up a variable that will hold the total of the images / scripts to be loaded
Set up a counter variable
Attach to each image / script the "onload" event
Everytime the "onload" event is triggered it will call a function that will increment the counter variable and check if the value of the counter equals the value of the total variable
If all resources have been loaded, fire a custom event that will show the div with the images, and hide the div with the loading screen.
The code below isn't tested so it might not work. Hope it helps
var totalImages = 0;
var loadCounter = 0;
function incrementLoadCounter() {
loadCounter++;
if(loadCounter === totalImages) {
$(document).trigger('everythingLoaded');
}
}
function hideLoadingScreen() {
$('#loadingScreen').hide();
$('#divWithImages').show();
}
$(document).ready(function(e) {
$('#loadingScreen').bind('everythingLoaded', function(e) {
hideLoadingScreen();
});
var imagesToLoad = $('img.toLoad');
totalImages = imagesToLoad.length;
$.each(imagesToLoad, function(i, item) {
$(item).load(function(e) {
incrementLoadCounter();
})
});
})
I'm not sure if it's possible to enforce.
If it is, try adding this in the head-tag:
<script type="text/javascript">
if(document.images)
(new Image()).src="http://www.image.com/example.png";
</script>
In theory that may load and cache that image before anything else.
I think if you place the IMG tag at the top of your html body it will be loaded first. If you do not want to move your div just use a copy of the image tag. Once the images is loaded it will be shown in every image tag which shows the same picture.
Or you could use spin.js as loading image. It display this "loading cycle image" via javascript.
Check it out under:
http://fgnass.github.com/spin.js/
I just need a jQuery snippet to do the prepend in img src , i.e
<img src='/img/picture1.jpg' />
The code snippet jQuery is to prepend this url
http://cdn.something.com/
so after the snippet jQuery, it becomes like
<img src='http://cdn.something.com/img/picture1.jpg' />
Any help is greatly appreciated.
so far I wrote something like
$().ready(function(){
var cdn ='http://cdn.something.com';
$('img').attrib('src', cdn);
});
However it is replaced the src rather than pre
it's not really jQuery related, anyway you could do it with .attr()what is that?:
$('img').attr('src', function(index, src) {
return 'http://cdn.something.com' + src;
});
This would affect all of your <img> nodes in your markup and replace the src.
Anyway, I'm not so sure that this is a great idea. At the time theDOMready event fires, a browser might already have tried to access the old source attribute. If you must do this in Javascript, it's probably a better idea to store the path info within a custom data attribute so a browser is not tempted to load the image. This could look like:
HTML
<img src='' data-path='/img/picture1.jpg' />
JS
$(function() {
$('img').attr('src', function(index, src) {
return 'http://cdn.something.com' + this.getAttribute('data-path');
});
});
This should do it. You could replace this.getAttribute() by $(this).data('path') since jQuery parses those data attributes into it's "node" data hash. But this would create another jQuery object, which really is unecessary at this point.
This should work:
$.ready(function() {
$('img').each(function() {
$(this).attr('src', cdn + $(this).attr('src'));
});
});
However I'm not sure it is the good solution for using a CDN, as the browser will have already tried to load the images from your server at the time the script will be called.
You should do this on the server side instead.
Depending what your specific problem is, you might be able to sort out this problem with a base tag, but I assume you will only want this on images, but changing the src once the page has loaded will make the images reload? IF the images don't exist in the current location you will need to change the src attribute before the page is loaded (server side).