Execute js after all image loaded not working - javascript

(not duplicate, because not find exactly/easy solution)
I'm trying to execute JS after all images completely loaded. My goal is, when all images finish load completely, then removeClass my-loader and addClass visible to main-slider div.
HTML:
<div class='main-slider my-loader'>
<img src="https://unsplash.it/200/300/">
<img src="https://unsplash.it/200/300/">
<img src="https://unsplash.it/200/300/">
</div>
Execute below js when all images completely loaded
$(".main-slider").removeClass("my-loader").addClass("visible");
Tried this js :
But not works properly on my site, problem is when i clear browser cache, then it works/execute! when i reload page then next time it's not works/execute! It only works when i clear browser cache.
var img = $('.main-slider img')
var count = 0
img.each(function(){
$(this).load(function(){
count = count + 1
if(count === img.length) {
$('.main-slider').removeClass('my-loader').addClass('visible')
}
});
});
Any simple solution? Thanks in advance.

jQuery provides a way to register a callback for the window load event which will fire when the entire page, including images and iframes, are loaded.
Reference: https://learn.jquery.com/using-jquery-core/document-ready/
Your code should look something like:
$( window ).load(function () {
var img = $('.main-slider img')
var count = 0
img.each(function(){
$(this).load(function(){
count = count + 1
if(count === img.length) {
$('.main-slider').removeClass('my-loader').addClass('visible')
}
});
});
});

Here's how to do this, using Deferreds and native handlers, and calling the onload handler if the image is cached in older browsers etc.
var img = $('.main-slider img');
var defs = img.map(function(){
var def = new Deferred();
this.onload = def.resolve;
this.onerror = def.reject;
if (this.complete) this.onload();
return def.promise();
});
$.when.apply($, defs).then(function() {
$('.main-slider').removeClass('my-loader').addClass('visible')
});

Related

Start javascript after lazy load images

I have a problem with a javascript. The script causes three elements on my website to be the same size. I would like to load my pictures by lazy load. This makes the rendering incorrect because the size of the elements is calculated by the script without the images. Is it possible to give the javascript a function that it will start only after the images have been loaded successfully by lazy load?
<script type="text/javascript">
jQuery(document).ready(function($){
function kb_equal_height() {
var highest_element = 0;
// Delete the height
$('.navigation-left,.site-content,.widget-area').each(function() {
$(this).removeAttr('style');
});
// Check which element is highest
$('.navigation-left,.site-content,.widget-area').each(function() {
if ($(this).height() > highest_element) {
highest_element = $(this).height();
}
});
// Assign this height to all elements
$('.navigation-left,.site-content,.widget-area').each(function() {
$(this).height(highest_element);
});
};
window.onload = kb_equal_height;
var resizeTimer;
$(window).resize(function() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(kb_equal_height, 100);
});
});
</script>
You can use image.onload to call the function when the image finished to load
You might not really see it in action here as the images probably won't take long enough to load for you to see intermediate state but it works
you'll need to clean your cache if you want to see it in action a second time as your browser will load the images from cache the second, third... times
let nbCat = 0
let div = document.getElementById("nbImg")
Array.from(document.getElementsByClassName("doAction")).forEach(img => {
img.onload = imgLoaded // your function here
})
function imgLoaded(e) {
nbCat++
div.textContent = nbCat + " cat" + (nbCat > 1? "s":"") + " loaded"
}
img {
max-height: 50vh
}
<img class="doAction" src="https://r.hswstatic.com/w_907/gif/tesla-cat.jpg">
<img class="doAction" src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg">
<img class="doAction" src="https://pre00.deviantart.net/5d96/th/pre/f/2012/103/d/d/dd0d35acf8ea1817dffe7677f018b5a4-d4vzsbg.jpg">
<img class="doAction" src="https://pre00.deviantart.net/758d/th/pre/f/2018/006/2/7/tigerfieldadjusted_by_mssylviarose-dbz65qt.jpg">
<div id="nbImg">no cat loaded</div>

Why does this "loading message" script not work in FF?(javascript)

I have this script which should show the text "Loading..." while images are loading, then change the text to "loaded" when all images are loaded. I added a button to load new images to make sure that it works for dynamically loaded images as well.
This works perfectly in Chrome but in Firefox the "Loading..." text never appears. I have no idea why this would be. The page begins loading and not all images are loaded so it should create the text "Loading.." but it doesn't. Then when all images are done loading the text "Loading" appears.
I just don't get why one message would appear and the other wouldn't. Especially because there are no qualifications that have to be met before creating the "Loading..." text, it should just fire automatically.
jsfiddle Example | Full Page Example
$(document).ready(function() {
var checkComplete = function() {
if($('img').filter(function() {return $('img').prop('complete');}).length == $('img').length) {
$('.status').text('Loaded');
} else {
$('.status').text('Loading...');
}
};
$('img').on('load',function() {
checkComplete();
});
$('#button').click(function() {
$('img.a').attr('src' , 'http://farm9.staticflickr.com/8545/8675107979_ee12611e6e_o.jpg');
$('img.b').attr( 'src' , 'http://farm9.staticflickr.com/8382/8677371836_651f586c99_o.jpg');
checkComplete();
});
checkComplete();
});
You have several issues in the code.
First off, the checkComplete() function is not written correctly. It should be this:
var checkComplete = function() {
var imgs = $('img');
if(imgs.filter(function() {return this.complete;}).length == imgs.length) {
$('.status').text('Loaded');
} else {
$('.status').text('Loading...');
}
};
The main fix here is that the filter callback needs to refer to this.complete, not to $('img').prop('complete') because you are trying to filter a single item at a time.
Second off, you are relying on both .complete and .load working correctly AFTER you've changed the .src value. This is explicitly one of the cases where they do not work properly in all browsers.
The bulletproof way to work around this is to create a new image object for the new images, set the onload handler before you set the .src value and when both onload handlers have fired, you will know that both new images are loaded and you can replace the once you have in the DOM with the new ones.
Here is a version that works in FF:
$(document).ready(function() {
$('#button').click(function() {
var imgA = new Image();
var imgB = new Image();
imgA.className = "a";
imgB.className = "b";
var loaded = 0;
imgA.onload = imgB.onload = function() {
++loaded;
if (loaded == 2) {
$("img.a").replaceWith(imgA);
$("img.b").replaceWith(imgB);
$('.status').text('Loaded');
}
}
// the part with adding now to the end of the URL here is just for testing purposes to break the cache
// remove that part for deployment
var now = new Date().getTime();
imgA.src = 'http://farm9.staticflickr.com/8545/8675107979_ee12611e6e_o.jpg?' + now;
imgB.src = 'http://farm9.staticflickr.com/8382/8677371836_651f586c99_o.jpg?' + now;
$('.status').text('Loading...');
});
});
Working demo: http://jsfiddle.net/jfriend00/yy7GX/
If you want to preserve the original objects, you can use the newly created objects only for preloading the new images and then change .src after they've been preloaded like this:
$(document).ready(function() {
$('#button').click(function() {
var imgA = new Image();
var imgB = new Image();
var loaded = 0;
imgA.onload = imgB.onload = function() {
++loaded;
if (loaded == 2) {
$("img.a")[0].src = imgA.src;
$("img.b")[0].src = imgB.src;
$('.status').text('Loaded');
}
}
// the part with adding now to the end of the URL here is just for testing purposes to break the cache
// remove that part for deployment
var now = new Date().getTime();
imgA.src = 'http://farm9.staticflickr.com/8545/8675107979_ee12611e6e_o.jpg?' + now;
imgB.src = 'http://farm9.staticflickr.com/8382/8677371836_651f586c99_o.jpg?' + now;
$('.status').text('Loading...');
});
});
Working demo of this version: http://jsfiddle.net/jfriend00/ChSQ5/
From the jQuery API .load method
Caveats of the load event when used with images
A common challenge developers attempt to solve using the `.load()` shortcut is to execute a function when an image (or collection of images) have completely loaded. There are several known caveats with this that should be noted. These are:
It doesn't work consistently nor reliably cross-browser
It doesn't fire correctly in WebKit if the image src is set to the same src as before
It doesn't correctly bubble up the DOM tree
Can cease to fire for images that already live in the browser's cache

javascript preloader/progress/percentage

I'm having trouble finding any good information on how to make a javascript(or jquery) progress bar WITH text that tells you the percentage.
I don't want a plug in, I just want to know how it works so that I can adapt it to what I need. How do you preload images and get a variable for the number of images that are preloaded. Also, how do you change html/css and-or call a function, based on the number of images that are loaded already?
<img> elements have an onload event that fires once the image has fully loaded. Therefore, in js you can keep track of the number of images that have loaded vs the number remaining using this event.
Images also have corresponding onerror and onabort events that fire when the image fails to load or the download have been aborted (by the user pressing the 'x' button). You also need to keep track of them along with the onload event to keep track of image loading properly.
Additional answer:
A simple example in pure js:
var img_to_load = [ '/img/1.jpg', '/img/2.jpg' ];
var loaded_images = 0;
for (var i=0; i<img_to_load.length; i++) {
var img = document.createElement('img');
img.src = img_to_load[i];
img.style.display = 'hidden'; // don't display preloaded images
img.onload = function () {
loaded_images ++;
if (loaded_images == img_to_load.length) {
alert('done loading images');
}
else {
alert((100*loaded_images/img_to_load.length) + '% loaded');
}
}
document.body.appendChild(img);
}
The example above doesn't handle onerror or onabort for clarity but real world code should take care of them as well.
What about using something below:
$('#btnUpload').click(function() {
var bar = document.getElementById('progBar'),
fallback = document.getElementById('downloadProgress'),
loaded = 0;
var load = function() {
loaded += 1;
bar.value = loaded;
/* The below will be visible if the progress tag is not supported */
$(fallback).empty().append("HTML5 progress tag not supported: ");
$('#progUpdate').empty().append(loaded + "% loaded");
if (loaded == 100) {
clearInterval(beginLoad);
$('#progUpdate').empty().append("Upload Complete");
console.log('Load was performed.');
}
};
var beginLoad = setInterval(function() {
load();
}, 50);
});
JSFIDDLE
You might also want to try HTML5 progress element:
<section>
<p>Progress: <progress id="p" max=100><span>0</span>%</progress></p>
<script>
var progressBar = document.getElementById('p');
function updateProgress(newValue) {
progressBar.value = newValue;
progressBar.getElementsByTagName('span')[0].textContent = newValue;
} </script>
</section>
http://www.html5tutorial.info/html5-progress.php

Javascript taking too long to load

The javascript of the div "intro" is loading at last. It's taking too long to load as the web page loads the bg image first and then loads the java script. Is there a way i can display "loading please wait" message in that "intro" div until it completely loads. I just want that the intro should load first.
Javascript code:
var tl = new Array(
"=======================",
" Welcome user, ",
" ###########################################"
);
var speed = 50;
var index = 0;
text_pos = 0;
var str_length = tl[0].length;
var contents, row;
function type_text() {
contents = '';
row = Math.max(0, index - 20);
while (row < index)
contents += tl[row++] + '\r\n';
document.forms[0].elements[0].value = contents + tl[index].substring(0, text_pos) + "_";
if (text_pos++ == str_length) {
text_pos = 0;
index++;
if (index != tl.length) {
str_length = tl[index].length;
setTimeout("type_text()", 500);
}
}
else setTimeout("type_text()", speed);
}
This is the script and its basically typing letter by letter in a text area in the div "intro". The problem is that it loads at last when the whole page has loaded. It starts printing the text after like 15 seconds or so.
There are "domready" events you can listen to on the document but seems that's not cross-browser.
Eg: Mozilla
document.addEventListener("DOMContentLoaded", methodName, false)
A better option is to use jQuery's .ready() event. They handle all cross-browser implementations.
Eg:
$(document).ready(function(){
//execute code here
});
//Shorthand
$(function(){
//...
});
See this related question for more on domready.
Load a page with the empty intro div, run the script with "loading please wait" then trigger an ajax request to load the rest of the page and update the page on onComplete event from the ajax request
Using jQuery
$(document).ready(function() {
// update div here
});
http://api.jquery.com/ready/
Or you could do that with
window.onload= (function() {
// update div here
};
You can use jquery for this by wrapping the content in a div tag and then another div that holds a loading image, something to this effect:
$(document).ready(function () {
$('#loading').show();
$('#divShowMeLater').load(function () {
$('#loading').hide();
$('#divShowMeLater').show();
});
})
Assume divShowMeLater is the div that contains all the content being loaded. The markup would look similiar to this:
<div id="divShowMeLater" style="margin-left:auto;margin-right:auto;text-align:center;" >
<div id="loading">Page loading...
<img src="images/ajax-loader.gif" alt="loading page..." />
</div>
</div>

How can i know if all <img> loaded in div using jQuery

How can i know if all loaded in div using jQuery
i want to do this after load all img in #slider div
var imgHeight = $("#slider img").height();
alert(imgHeight);
You can use the load event
$('#slider img').load(function(){
var imgHeight = $(this).height();
alert(imgHeight);
});
if there are more than one image, and you only want to obtain the height after they have all loaded, try this code
var img = $('#slider img');
var length = img.length;
img.load(function(){
length--;
if(length === 0){
alert("All images loaded");
};
});
Well, I've tested the code, and it appears that the problem hasn't got anything to do with the code. When loading the page with the images already in the cache, this is what I get:
Strangely, this does not occur when I force the browser not to use the cache.
Try this:
Attach an onload event listener to each image in the slider.
In the listener:
Give the current image a custom attribute to mark it is 'ready'.
Check if all images are ready. If so, do your thing (i.e. alert(imageHeight))
untested:
(function(){
var slider=document.getElementById('slider'),
images=slider.getElementsByTagName('img'), image, i=-1;
while (image=images[i]) {
image.onload=function(){
this['data-ready']=true;
var image, i=-1;
while (image=images[i]) if (!image['data-ready']) return;
// all images are ready; do your thing here
// ...
}
}
}());

Categories