Detect dynamically appended images load event pure javascript [duplicate] - javascript

Say, user opens a page, clicks on a button, and popup with images appears. How do I detect when all of the images have been loaded? I can't use window.onload here, since the page had already been loaded with all the assets. To make it clear, I want to find out final extents of the popup.
Popup is added to DOM like so:
var popup = document.createElement('div');
popup.innerHTML = '...';
document.body.appendChild(popup);

Simply:
var image = document.getElementById('image');
image.onload = function () {
alert ("The image has loaded!");
};
setTimeout(function(){
image.src = "http://lorempixel.com/500/500";
}, 5000);
<img id="image" src="">
See https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload and Javascript callback for knowing when an image is loaded for more.

Based on this answer. Hopefully that is enough.
var cons = document.querySelector('#console');
var popup = document.createElement('div');
popup.className = 'popup';
popup.innerHTML = _.range(10).map(function(i) {
return '<img src="http://via.placeholder.com/50/50">';
}).join('');
document.body.insertBefore(popup, cons);
waitForImages(popup).then(function() {
d('loaded');
})
function d(s) {
var text = document.createTextNode(s);
cons.appendChild(text);
var br = document.createElement('br');
cons.appendChild(br);
}
function waitForImages(el) {
var images = document.querySelectorAll('img');
return Promise.all(_.compact(_.map(images, function(img) {
if (img.complete) {
d('img.complete');
return;
} else
return new Promise(function(resolve, reject) {
img.addEventListener('load', function() {
d('onload event');
resolve();
});
});
})));
}
.popup {
overflow: hidden;
}
img {
float: left;
margin: 0 5px 5px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.5.0/bluebird.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<div id="console">
</div>

Related

Defer image and replacement loaded

I have a JS function that once the page is loaded swaps the assets from a transparent gif to full images via the data-src below.
<img src="1x1.gif" data-src="full-photo.png" class="asset" /> // My image
window.addEventListener('load', function() {
defer_images();
function defer_images() {
var loadedImages = 0;
var imgDefer = document.getElementsByClassName('asset');
for (var i = 0; i < imgDefer.length; i++) {
if (imgDefer[i].getAttribute('data-src')) {
imgDefer[i].setAttribute('src',imgDefer[i].getAttribute('data-src'));
var iWidth = imgDefer[i].naturalWidth; // Check image exists
if (iWidth) {
loadedImages++;
} else {
console.log("Image missing: "+imgDefer[i].getAttribute('data-src'));
}
}
// all images exist and have been replaced
if (imgDefer.length === loadedImages) {
doThings();
}
}
}
});
This seems to work fine on a cached page. But if I reload the page and switch tabs – the code doesn't complete as loadedImages++ is never fired.
I can't use setInterval or setTimeout to re-check as this code is used in DoubleClick.
Any help would be really appreciated.
You can detect that images are loaded by using the onload event and failed to load using onerror.
for (var i = 0; i < imgDefer.length; i++) {
var img = imgDefer[i];
if (img.getAttribute('data-src')) {
img.addEventListener("load", function() {
loadedImages++;
});
img.addEventListener("error", function() {
console.log("Image missing: "+ this.getAttribute("data-src"))
});
img.src = img.getAttribute('data-src');
}
}
The reason it fails for non-cached is because it takes time to load the image, and your for loop is fast. Use the events to trigger when the image is loaded.
You can read more here.
Note: Detecting that all images are loaded may require using promises:
function loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.addEventListener("load", () => resolve(img));
img.addEventListener("error", err => reject(err));
img.src = src;
// append to the dom or replace here
});
};
Then you can use then() and catch()

Detect when images added to DOM have been loaded

Say, user opens a page, clicks on a button, and popup with images appears. How do I detect when all of the images have been loaded? I can't use window.onload here, since the page had already been loaded with all the assets. To make it clear, I want to find out final extents of the popup.
Popup is added to DOM like so:
var popup = document.createElement('div');
popup.innerHTML = '...';
document.body.appendChild(popup);
Simply:
var image = document.getElementById('image');
image.onload = function () {
alert ("The image has loaded!");
};
setTimeout(function(){
image.src = "http://lorempixel.com/500/500";
}, 5000);
<img id="image" src="">
See https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload and Javascript callback for knowing when an image is loaded for more.
Based on this answer. Hopefully that is enough.
var cons = document.querySelector('#console');
var popup = document.createElement('div');
popup.className = 'popup';
popup.innerHTML = _.range(10).map(function(i) {
return '<img src="http://via.placeholder.com/50/50">';
}).join('');
document.body.insertBefore(popup, cons);
waitForImages(popup).then(function() {
d('loaded');
})
function d(s) {
var text = document.createTextNode(s);
cons.appendChild(text);
var br = document.createElement('br');
cons.appendChild(br);
}
function waitForImages(el) {
var images = document.querySelectorAll('img');
return Promise.all(_.compact(_.map(images, function(img) {
if (img.complete) {
d('img.complete');
return;
} else
return new Promise(function(resolve, reject) {
img.addEventListener('load', function() {
d('onload event');
resolve();
});
});
})));
}
.popup {
overflow: hidden;
}
img {
float: left;
margin: 0 5px 5px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.5.0/bluebird.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<div id="console">
</div>

Why is only the first mouse-over and mouse-out working?

I have loaded a set of images and applied .mouseout() and .mouseover() on them. The problem is that after the first .mouseover() event the image gets larger and after .mouseout() is fired the image is returned back to its previous size. After the first time, no .mouseover() event gets fired in Firefox, but in Chrome it works. The problem is that the Chrome z-index property does not put the mouseover image on top of other images. What is the reason for these problems and how can I solve them?
var images = ['http://www.rd.com/wp-content/uploads/sites/2/2016/04/01-cat-wants-to-tell-you-laptop.jpg', 'http://r.ddmcdn.com/s_f/o_1/cx_462/cy_245/cw_1349/ch_1349/w_720/APL/uploads/2015/06/caturday-shutterstock_149320799.jpg', 'http://r.ddmcdn.com/s_f/o_1/cx_462/cy_245/cw_1349/ch_1349/w_720/APL/uploads/2015/06/caturday-shutterstock_149320799.jpg', 'http://pershanpet.ir/wp-content/uploads/2016/05/144-jpravafcbn.jpg', 'http://www.animal-whisper.com/images/pic28.jpg'];
function loadImage(url) {
var promise = new Promise((resolve, reject) => {
var image = new Image();
image.onload = function() {
resolve(image);
};
image.onerror = function() {
var msg = "could not load image at url " + url;
reject(new Error(msg));
};
image.src = url;
image.style.width = '200px';
image.style.height = '200px';
});
return promise;
}
Promise.all(
images.map(function(elem) {
return loadImage(elem);
})
).then((img) => {
img.forEach(each => {
each.addEventListener('mouseover', function(event) {
this.style.zIndex = '2000';
this.style.transform = 'scale(1.5,1.5)';
});
each.addEventListener('mouseout', function(event) {
this.style.transform = 'scale(1,1)';
this.style.zIndex = '-1';
});
addImg(each);
});
});
function addImg(img) {
document.body.appendChild(img);
}
Maybe your images get under some other elements with z-index that is greater than -1. On mouseout try this.style.zIndex = '0'.
It appears that you're setting the image's z-index to -1. Any reason for that?
Try setting this.style.zIndex = '1'; on mouseout.

JQuery - Check to see if an IMG src is valid

Is it possible to check to see if an img src is valid using jquery?
We have a dynamic site with hundreds of news articles - the majority of which contain images - basically theres a back-end bug and even if there isn't an image currently the image div is displayed - which is causing us a few issues.
<div class="imgBlock">
<img class="newsImg" src="db/imgart/10234.jpg" />
</div>
Is it possible to detect whether the img src is delivering an image via JQuery script?
function IsValidImageUrl(url) {
$("<img>", {
src: url,
error: function() { alert(url + ': ' + false); },
load: function() { alert(url + ': ' + true); }
});
}
Use the error handler like this:
$(".newsImg").error(function() {
alert("No image");
});
Or
var image = new Image();
image.src = "db/imgart/10234.jpg";
if (image.width == 0) {
alert("No image");
}
Use simple css:
<style type="text/css">
.hidden {
display: none;
{
.visible {
display: block;
}
</style>
then script
var imgDiv = document.getElementById('img1'); //your div id
var imgsrc = "db/imgart/10234.jpg"; //or document.getElementById(img1).getElementsByTagName('img');
var img = new Image();
img.onerror = function (evt){
alert(this.src + " can't be loaded.");
//hide <div>
imgDiv.setAttribute('class', 'hidden');
}
img.onload = function (evt){
alert(this.src + " is loaded.");
//show div
imgDiv.setAttribute('class', 'visible');
}
img.src = imgsrc;

jQuery switch image with fade

I have a script which changes some images on hover. Works really well, however I would like to add a little fade between the two images. Here is the script. Really new to jQuery so I'm a little confused where to add it. Any help would be appreciated
jQuery(document).ready(function ($) {
var img_src = "";
var new_src = "";
$(".rollover").hover(function () {
img_src = $(this).attr('src');
new_src = $(this).attr('rel');
$(this).attr('src', new_src);
$(this).attr('rel', img_src);
}, function () {
$(this).attr('src', img_src);
$(this).attr('rel', new_src);
});
//preload images
var cache = new Array();
//cycle through all rollover elements and add rollover img src to cache array
$(".rollover").each(function () {
var cacheImage = document.createElement('img');
cacheImage.src = $(this).attr('rel');
cache.push(cacheImage);
});
function imageSwitch(img) {
var src = img.attr('src');
var rel = img.attr('rel');
img.fadeOut('fast', function() {
img.attr('src', rel);
img.attr('rel', src);
img.fadeIn('fast');
});
}
$(".rollover").on('mouseenter', function() {
imageSwitch($(this));
});
a small search give me that : http://www.simonbattersby.com/demos/crossfade_demo_basic.htm i think it's kinda what you're looking for.
or else you with thread that do something also :
jQuery Change Image src with Fade Effect
it would be better to use .mouseenter for this.
and you could do .animate() opacity to 0 and in the call back you would change the image src, so that the src change after the animation ended.
$('.rollover').mouseenter(function () {
var me = $(this),
new_src = me.attr('rel'),
anmiation_duration = 300; // 300ms
me.animate({
opacity: 0
}, anmiation_duration, function () {
me.attr('src', new_src).css({'opacity':'1'});
})
});
After the src is changed you can do another .animate() to set the opacity back to 1.
I would however suggest to have the other image already displayed behind the first image, (images placed over each other using position:absolut). That way the opacity change would create sort of morf effect.
Briefly tested, thanks to #Oksid for the mouseenter comment.
EDITED
The HTML:
<img class="front rollover" src="http://placehold.it/350x150/006699" rel="http://placehold.it/350x150/000000" />
The CSS:
.image_holder {
position: relative;
}
.image_holder img {
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
.image_holder img.front {
z-index: 2 !important;
}
The jQuery:
function init_rollovers() {
$(".rollover").each(function() {
var w = $(this).width()+'px';
var h = $(this).height()+'px';
var src = $(this).attr('src');
var rel = $(this).attr('rel');
$(this).addClass('shown');
if (!$(this).parents('.image_holder').length) {
$(this).wrap('<div class="image_holder" style="width:'+w+';height:'+h+';"></div>');
$(this).parents('.image_holder').append('<img src="'+rel+'" />');
}
});
}
init_rollovers();
function doImageSwitch(el, speed=425) {
var front = el.find(".front");
if (front.hasClass('shown')) {
front.fadeTo(speed, 0, function() {
$(this).removeClass('shown');
});
}
else {
front.animate({
opacity: 1
}, speed, function() {
$(this).addClass('shown');
});
}
}
$(document).on('mouseenter', '.image_holder', function() {
doImageSwitch($(this));
});

Categories

Resources