Reputation: 26678
I have this bit of JavaScript:
function performSearch(keywords) {
const itemList = document.getElementById('items-div');
const search = document.getElementById('search');
itemList.innerHTML = '';
setLoading(true);
store.where({ name: keywords }).then((items) => {
setLoading(false);
console.log(`Found ${items.length} items...`);
items.forEach((c, i) => {
console.log(c);
if (c.imageUrl) {
itemList.innerHTML += rowTemplate({
card: c,
index: i,
});
const img = document.getElementById(`image-${i}`);
img.onload = () => {
img.style.transition = "opacity 0.3s";
img.style.opacity = "1";
console.log(`Image ${i} loaded succesfully.`);
};
img.src = c.imageUrl;
}
});
search.focus();
search.select();
});
}
The bit that doesn't seem to work is the img.onload
part.
The console.log()
message is displayed in the console, however, the opacity does not change.
If I do the exact same thing in the console itself, it works fine.
I realize this must be because the DOM isn't done rendering the stuff I'm adding yet, but I'm not sure how to fix it.
Upvotes: 1
Views: 400
Reputation: 16384
Because you need to specify starter opacity
on load (it's 1
by default, and you're trying to transition from 1
to 1
which has no visible effect). And you can achieve fade-in
effect via @keyframes
, here is an example:
const onload = () => {
const img = document.getElementById('target');
img.style.opacity = 0;
img.style.animation = "fadeIn .5s ease-in 1 forwards";
};
onload();
@keyframes fadeIn {
to {
opacity: 1;
}
}
<img src="http://qnimate.com/wp-content/uploads/2014/03/images2.jpg" id="target">
"This sort of displays what I mean: jsfiddle.net/92w79gxa/3 ... in this example, I am showing all of the images by default, but then trying to make them all fade away. Only the last one fades."
You need to assign new value inside img.onload
: img = document.getElementById('some-image-${i}');
. Here is the working example:
const stuff = document.getElementById("stuff");
stuff.innerHTML = '';
console.log('started');
for(let i = 0; i <= 5; i++) {
stuff.innerHTML += `
<img style="opacity: 1" id="some-image-${i}" width="20" height="20"><br>
`;
let img = document.getElementById(`some-image-${i}`);
console.log('BEFORE "onload"')
img.onload = () => {
console.log('INSIDE "onload"')
img = document.getElementById(`some-image-${i}`);
img.style.transition = 'opacity 2s';
img.style.opacity = '0';
};
img.src = 'http://synic.world/s/someicon.png';
}
console.log('Done!');
<div id="stuff">
</div>
If you will look at console logs, you will see, that all iterations goes first, and only after the last one is finished, all onload
will be executed, and the last stored item will be .some-image-5
(it's because only last item was faded).
Upvotes: 2
Reputation: 23
I think it has to do with the scoping of the for loop. Your JSFiddle example only fades the last image. I used lodash to make sure the scope is correct.
https://jsfiddle.net/92w79gxa/4/
const stuff = document.getElementById("stuff");
stuff.innerHTML = '';
_.each(_.range(5), i => {
stuff.innerHTML += `
<img style="opacity: 1" id="some-image-${i}" width="20" height="20"><br>
`;
})
const images = document.getElementsByTagName('img');
_.each(images, (img, i) => {
img.onload = () => {
img.style.transition = 'opacity 2s';
img.style.opacity = '0';
console.log(`Loaded image ${i}`);
console.log(img);
};
img.src = 'http://synic.world/s/someicon.png';
});
Upvotes: 1