Show loading gif while image is loading - javascript

I made some code where the user can upload some images from a zip. On the next page I need to show all the images seperatly in a 85*85 px frame.
The problem is that it may take some time for all the images to load. So I want to show a loading gif while the user waits for the image to load.
I've set the src of the images to be the loading gifs, while I created some checkboxes with the real source as id
echo "<td><img src=\"beelden/ajax-loader-black-16.png\" id=\"img".$image."\" style=\" width: 85px; height: 85px; border: 1px solid gray; background-color: #fff; padding: 10px;\">";
echo "<input type=\"checkbox\" id=\"img[".$image."]\" name=\"check_image[]\" value=\"".$filename."\" /></td>";
<input type="hidden" name="aantal" id="aantal" value="<?=$image?>" >
Then I created some javascript to check if the image is loaded, and when it is, it is supposed to replace the source of the image.
<script>
var aantal = document.getElementById("aantal").value;
for(var i = 0; i < aantal; i++){
var source = document.getElementById("img["+i+"]").value;
var img = new Image();
img.onload = function(){
$("#img"+i).attr('src', source);
}();
img.src = source;
}
</script>
But this does not work the way I expected, I think it fires for all of the images as soon as the first one is loaded. Any ideas what I am doing wrong or how to fix this?

You can set the background of an image to the loading gif. It is a simple css trick. You wouldn't need then to make a js script.
.loading {
background: transparent url('http://thinkfuture.com/wp-content/uploads/2013/10/loading_spinner.gif') center no-repeat;
}
<img class="loading" src="http://placehold.it/106&text=1" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=2" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=3" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=4" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=5" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=6" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=7" width="106px" height="106px" />
Update :
In case you have transparent images then the story becames a bit more complicated but, still can be done with css and some div elements.
.image-wrapper {
overflow: hidden;
width: 106px;
height: 106px;
display: inline-block;
}
.image-wrapper img {
float: left;
display: block;
opacity: 0.2; /* simulating a semitransparent image */
}
.image-wrapper:after, .loading {
content: ' ';
background: transparent url('http://thinkfuture.com/wp-content/uploads/2013/10/loading_spinner.gif') center no-repeat ;
background-size : auto 100%;
width: 106px;
height: 106px;
float: left;
display: block;
}
<div class="image-wrapper">
<!-- simulates a hard loading image -->
<img src="http://placehold.it/not-existing" alt="" />
</div>
<div class="image-wrapper">
<img src="http://placehold.it/106x106&text=2" alt="" />
</div>
<div class="image-wrapper">
<img src="http://placehold.it/106x106&text=3" alt="" />
</div>
<div class="image-wrapper">
<img src="http://placehold.it/106x106&text=4" alt="" />
</div>
<div class="image-wrapper">
<img src="http://placehold.it/106x106&text=5" alt="" />
</div>
<div class="image-wrapper">
<img src="http://placehold.it/106x106&text=6" alt="" />
</div>
<div class="image-wrapper">
<img src="http://placehold.it/106x106&text=7" alt="" />
</div>
Unfortunately the browser adds a broken icon or a ? while loading, this is why the image contains an empty alt;
Update 2 :
The second variant relies very much on the image size, if you have difrent sizes than the loading gif won't be pushed away properly, as an alternative would be to use the first variant and a little js script that will remove the background as soon as the image is loaded:
$('img').load(function(){
$(this).css('background','none');
});
.loading {
background: transparent url('http://thinkfuture.com/wp-content/uploads/2013/10/loading_spinner.gif') center no-repeat;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img class="loading" src="http://upload.wikimedia.org/wikipedia/en/2/2d/SRU-Logo-Transparent.png" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=2" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=3" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=4" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=5" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=6" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=7" width="106px" height="106px" />

Angular 8 Solution with Hostlistener and Hostbinding.
1. Create a simple attribute directive
import { Directive, HostListener, Input, HostBinding } from '#angular/core';
#Directive({selector: '[imageLoader]'})
export class ImageLoaderDirective
{
#Input('src') imageSrc;
#HostListener('load')
loadImage()
{
this.srcAttr=this.imageSrc;
}
#HostBinding('attr.src') srcAttr="../../assets/pics/Loader.svg"
constructor() { }
}
Basically we set the initial image source to the loader image. Once the image loads(load event triggered), we listen to it and set the image source to the actual image.
2. Now use the just need to use the created attributes on your images.
<img imageLoader src='image.jpg'>
Using svg requires no styling changes, gif may require css changes.
You can visit the website for working implementation.

Related

Parallax back round with multiple layers

I am trying to make a parallax back round like this one link.
So far I've made this but I can't get the layers to scroll, here is the link to my code link.
I am also having bugs like the drop down menu (the lightning icon) is behind the back round and the header isn't fixed when scrolling.
Can anyone please send a a tutorial on how to do this specific parallax back round or fix my code, thank you.
Here is the parallax code:
Html:
<img class="scene" data-modifier="30" src="https://s.electerious.com/parallaxscene/p0.png" alt="Image error.">
<img class="scene" data-modifier="18" src="https://s.electerious.com/parallaxscene/p1.png" alt="Image error.">
<img class="scene" data-modifier="12" src="https://s.electerious.com/parallaxscene/p2.png" alt="Image error.">
<img class="scene" data-modifier="8" src="https://s.electerious.com/parallaxscene/p3.png" alt="Image error.">
<img class="scene" data-modifier="6" src="https://s.electerious.com/parallaxscene/p4.png" alt="Image error.">
<img class="scene" data-modifier="0" src="https://s.electerious.com/parallaxscene/p6.png" alt="Image error.">
CSS:
body {
height: 2000px;
background: black;
}
.scene {
position: absolute;
width: 100%;
transform: translateY(var(--translateY));
will-change: transform;
}
Javascript:
document.querySelectorAll('.scene').forEach((elem) => {
const modifier = elem.getAttribute('data-modifier')
basicScroll.create({
elem: elem,
from: 0,
to: 519,
direct: true,
props: {
'--translateY': {
from: '0',
to: `${ 10 * modifier }px`
}
}
}).start()
})

How to make a gif animate on hover, go back to normal after unhovered

So I have a bunch of elements like:
<div class="hover-icon one">
<img class="original" src="sswe-images/Circle_Customer Notifications.png"/>
<img class="hovered one" src="sswe-images/Customer-Notifications.gif" />
</div>
<div class="hover-icon two">
<img class="original" src="sswe-images/Circle_Field Service Tools.png" />
<img class="hovered" src="sswe-images/Field-Service-Tools.gif" />
</div>
<div class="hover-icon three">
<img class="original" src="sswe-images/Circle_Remote Connectivity.png" />
<img class="hovered" src="sswe-images/Remote-Connectivity.gif" />
</div>
where the .original are placeholders and the .hovered are gifs that I want to animate on hover, then go back to their normal state after the mouse leaves. My attempt is:
$('div.hover-icon').hover(function(){
var orig = $(this).find('.original');
orig.hide();
var hov = $(this).find('.hovered');
hov.attr('src', hov.attr('src') + "?x=" + Math.random());
setTimeout(function(){ hov.show(); }, 100);
/* $(this).mouseleave(function(){
hov.hide();
orig.show();
});*/
});
but the reason for the commented out section is because it's not working. It's causing all kinds of craziness. What is the proper pattern I should be using here?
The basic HTML structure is correct. Use CSS only though , like this codepen http://codepen.io/ryanpcmcquen/pen/gGqdI does
.hover-icon {
position: relative;
margin: 0 auto;
}
.hover-icon img {
position: absolute;
}
.hover-icon img.original:hover {
opacity: 0;
}

CSS displaying elements when thumbnails are hovered over

i am attempting to display images when the corresponding thumbnail is hover over using only css and am having trouble with the logic and don't know if it is even possible. i can do it in javascript if absolutely necessary.
Here is my latest attempt.
<div id='img-container' class='grd12'>
<img id='img1' class='slide-images' src='images/10086115704_15ab56a165_o.jpg' alt='1'>
<img id='img2' class='slide-images' src='images/9917938624_0a8778f8b1_o.jpg' alt='2'>
<img id='img3' class='slide-images' src='images/PIA18847.jpg' alt='3'>
<img id='img4' class='slide-images' src='images/sun-large.jpg' alt='4'>
</div>
<!-- <div class='grd3 thumbnail'>-->
<img id='thumb1' class='grd3 thumbnail' src='images/10086115704_e36e457d2b_q.jpg' alt='##'>
<!-- </div>-->
<!-- <div class='grd3 thumbnail'>-->
<img id='thumb2' class='grd3 thumbnail' src='images/9917938624_1ed12deaa2_q.jpg' alt='##'>
<!-- </div>
<div class='grd3 thumbnail'>-->
<img id='thumb3' class='grd3 thumbnail' src='images/PIA18847.jpg' alt='##'>
<!--</div>
<div class='grd3 thumbnail'>-->
<img id='thumb4' class='grd3 thumbnail' src='images/sun-large.jpg' alt='##'>
<!--</div>-->
And the CSS
#img-container{
position:relative;
top:0px;
left:0px;
height:950px;
}
.slide-images{
position:absolute;
top:0px;
left:0px;
}
.thumbnail > img{
margin-left:auto;
margin-right:auto;
display: inherit;
}
img#thumb4:hover ~ #img4>#image4{
display:none;
}
I believe this is possible using CSS alone, however it is not very scaleable and it might end up being easier and more appropriate to use Javascript for this. For example:
img#thumb1:hover ~ #img4>#image4{
display:none;
}
Your selector here is incorrect. The general sibling selector selects only elements after the first match. In this case, your image thumb is after your image, but this selector is looking for an image after an image thumb. This is the opposite of what you have. There is no 'sibling before' selector in CSS.
An easier solution, rather than fiddling around with CSS selectors, would just be to bind each thumbnail to a click event that changes the source of a single image tag each time (or alternatively, scrolls across/fades, whatever animation you're looking for). This way, you save on markup, don't need to worry about positioning as much, and can dynamically generate the image display.
For example, to get the ID of an image, you could bind a click event to each thumbnail and then grab the ID of the image which could stored in a data attribute:
$('.thumbnail').on('hover', function() {
var activeImg = $(this).data('imgid');
// From here, set the main image to have the associated image source
}
This is very possible to achieve with just CSS. The layout of your HTML is what needs to change. In this example:
Each thumbnail and full-size image is placed inside a div container
The full-size image is hidden with opacity: 0;
When the div container is hovered, the full-size image is given opacity: 1 and will fade-in thanks to the transition
z-index: 1 keeps the full-size images above the thumbnails
Full Example
.item {
float: left;
position: relative;
}
img {
display: block;
cursor: pointer;
margin: 5px;
}
.fullsize {
position: absolute;
opacity: 0;
transition: opacity 0.6s;
z-index: 1;
top: 0;
left: 0;
pointer-events: none;
}
.item:hover .fullsize {
opacity: 1;
}
<div class="item">
<img class="fullsize" src="http://lorempixel.com/output/people-q-c-600-600-9.jpg" />
<img class="thumb" src="http://lorempixel.com/output/people-q-c-200-200-9.jpg" />
</div>
<div class="item">
<img class="fullsize" src="http://lorempixel.com/output/people-q-c-600-600-9.jpg" />
<img class="thumb" src="http://lorempixel.com/output/people-q-c-200-200-9.jpg" />
</div>
<div class="item">
<img class="fullsize" src="http://lorempixel.com/output/people-q-c-600-600-9.jpg" />
<img class="thumb" src="http://lorempixel.com/output/people-q-c-200-200-9.jpg" />
</div>
<div class="item">
<img class="fullsize" src="http://lorempixel.com/output/people-q-c-600-600-9.jpg" />
<img class="thumb" src="http://lorempixel.com/output/people-q-c-200-200-9.jpg" />
</div>
<div class="item">
<img class="fullsize" src="http://lorempixel.com/output/people-q-c-600-600-9.jpg" />
<img class="thumb" src="http://lorempixel.com/output/people-q-c-200-200-9.jpg" />
</div>
<div class="item">
<img class="fullsize" src="http://lorempixel.com/output/people-q-c-600-600-9.jpg" />
<img class="thumb" src="http://lorempixel.com/output/people-q-c-200-200-9.jpg" />
</div>

scrollHeight value for a div containing images

Here is a div, containing images, with max-height: 300px. Whenever a scrollbar is needed (this is the case here), I want to add a second div (the gray one) next to the first. I use scrollHeight to test the presence of a scrollbar.
<div class="container">
<div class="pictures">
<img src="test1.jpg" /> <img src="test2.jpg" /> <img src="test3.jpg" /> <img src="test4.jpg" />
<img src="test5.jpg" /> <img src="test6.jpg" /> <img src="test7.jpg" /> <img src="test8.jpg" />
<img src="test9.jpg" /> <img src="test10.jpg" /> <img src="test11.jpg" /> <img src="test12.jpg" />
<img src="test13.jpg" /> <img src="test14.jpg" /> <img src="test15.jpg" /> <img src="test16.jpg" />
<img src="test17.jpg" /> <img src="test18.jpg" /> <img src="test19.jpg" /> <img src="test20.jpg" />
<img src="test21.jpg" /> <img src="test22.jpg" />
</div>
<div class="scroll"></div>
</div>
Some CSS:
div.container {
width: 410px;
max-height: 300px;
overflow: auto;
}
div.container div.pictures {
float: left;
width: 390px;
}
div.container div.scroll {
display: none;
float: left;
width: 30px;
background-color: #eee;
}
And the JS:
$(function() {
$(".scroll").each(function() {
var iParentHeight = $(this).parent()[0].scrollHeight;
if (iParentHeight > $(this).parent().css("max-height").replace(/[^-\d\.]/g, '')) {
var iWidth = $(this).parent().width()+$(this).width();
$(this).parent().css("width", iWidth);
$(this).show();
$(this).height(iParentHeight);
}
});
});
On Firefox it's working. On Chrome and Safari though, there is some issue: sometimes (actually, most of the time for Safari) the gray dive does not appear when it should.
I made some tests: without images, with X time the same image and with X different images. The issue is only appearing when there is X different images (maybe some loading time problem?).
In fact, the output of scrollHeight is not always the same on Chrome and Safari. For FF, I always get the same result.
Any idea would be appreciated!
Edit: forgot the link with an example: http://toolboxebz.free.fr/test_scroll/test.html
I think that you should wrap your js function in a document.ready or utilize something like imageloaded, as you said the behaviour is not deterministic, that's due to the fact that when your function runs, images could be not already fully loaded in the browser.

Adding changing text onclick to JavaScript gallery

I'm trying to set up a simple gallery with thumbnails and a main content section. When a thumbnail is clicked, I would like a larger version of the image along with text to display in the main content section. I've got the code for the images down, but can't figure out how to add text on each click. I haven't started doing any styling yet, but the basic code is below. Any help would be much appreciated.
Thanks!
JavaScript:
var mainImg = document.getElementById('Main');
document.getElementById('One').onclick = function() {
mainImg.src = 'http://cdn.shopify.com/s/files/1/0176/5914/files/Kaylee_Radzyminski.jpg?7297';
mainImg.innerHTML = imagetitle;
//alert('one clicked');
};
document.getElementById('Two').onclick = function() {
mainImg.src = 'http://cdn.shopify.com/s/files/1/0176/5914/files/Mason_Hunter_Thornal.jpg?7297';
mainImg.innerHTML = 'imagetitle';
//alert('two clicked');
};
document.getElementById('Three').onclick = function() {
mainImg.src = 'http://cdn.shopify.com/s/files/1/0176/5914/files/Joseph_Nunez_4afb23ac-d71e-42a0-9366-ac78d65deaf4.jpg?7297';
//alert('two clicked');
};
CSS:
#One, #Two, #Three {
width:100px;
opacity: .5; /* css standard */
filter: alpha(opacity=50); /* internet explorer */
}
#One:hover, #Two:hover, #Three:hover {
width:100px;
opacity: 1; /* css standard */
filter: alpha(opacity=100); /* internet explorer */
}
HTML:
<img id="Main" src="http://cdn.shopify.com/s/files/1/0176/5914/files/Kaylee_Radzyminski.jpg?7297" alt="" />
<img id="One" src="http://cdn.shopify.com/s/files/1/0176/5914/files/Kaylee_Radzyminski.jpg?7297" alt="" />
<img id="Two" src="http://cdn.shopify.com/s/files/1/0176/5914/files/Mason_Hunter_Thornal.jpg?7297" alt="" />
<img id="Three" src="http://cdn.shopify.com/s/files/1/0176/5914/files/Joseph_Nunez_4afb23ac-d71e-42a0-9366-ac78d65deaf4.jpg?7297" alt="" />
http://jsfiddle.net/f9B8H/72/
Let's clean this up a bit.
HTML
<div id="container">
<img id="Main" src="http://cdn.shopify.com/s/files/1/0176/5914/files/Kaylee_Radzyminski.jpg?7297" alt="" />
<p id="caption"></p>
</div>
<img id="One" src="http://cdn.shopify.com/s/files/1/0176/5914/files/Kaylee_Radzyminski.jpg?7297" alt="I'm a soldier" />
<img id="Two" src="http://cdn.shopify.com/s/files/1/0176/5914/files/Mason_Hunter_Thornal.jpg?7297" alt="My family" />
<img id="Three" src="http://cdn.shopify.com/s/files/1/0176/5914/files/Joseph_Nunez_4afb23ac-d71e-42a0-9366-ac78d65deaf4.jpg?7297" alt="Dad" />
Notice how I've stored the caption in the alt attribute. A data attribute could also work.
JAVASCRIPT
function displayImage() {
var mainImg = document.getElementById('Main');
var caption = document.getElementById('caption');
mainImg.src = this.src;
caption.innerHTML = this.alt;
}
document.getElementById('One').onclick = displayImage;
document.getElementById('Two').onclick = displayImage;
document.getElementById('Three').onclick = displayImage;
Fiddle: http://jsfiddle.net/g2hY4/
The simplified function works so well because you are using the same image for thumbnail as main image. If you didn't do that, we could store the big image address in a data attribute also.
Here's one way to load the first caption when the page loads. Put it after the code I've already shown you:
displayImage.call(document.getElementById('One') );
You can read about call here. In a nutshell, it redefines the value of this in the displayImage function.
New fiddle
Something to think about is where you want the caption and how it's styled can be set in CSS. I've left that to you also. Absolute positioning will work if the positioning of #container is set to relative.
My implementation gets the text from the attribute alt(could be title) I think this way can be more elegant
document.getElementById('textSubtitle').innerHTML = this.alt;
http://jsfiddle.net/WKfc5/
If you are okay with using jQuery, here is something that I made up real quick. I hope it is useful. [Fiddle]
HTML
<div id="gallery">
<div class="preview">
<img class="previewImg" src="http://cdn.shopify.com/s/files/1/0176/5914/files/Kaylee_Radzyminski.jpg?7297" alt="" title="" />
<div class="previewText"></div>
</div>
<div class="thumbnails">
<a href="javascript: void(0);">
<img src="http://cdn.shopify.com/s/files/1/0176/5914/files/Kaylee_Radzyminski.jpg?7297" alt="" title="Image 1" />
</a>
<a href="javascript: void(0);">
<img src="http://cdn.shopify.com/s/files/1/0176/5914/files/Mason_Hunter_Thornal.jpg?7297" alt="" title="Image 2" />
</a>
<a href="javascript: void(0);">
<img src="http://cdn.shopify.com/s/files/1/0176/5914/files/Joseph_Nunez_4afb23ac-d71e-42a0-9366-ac78d65deaf4.jpg?7297" alt="" title="Image 3" />
</a>
</div>
</div>
CSS
#gallery {
overflow: hidden;
}
#gallery .preview {
float: left;
position: relative;
}
#gallery .previewImg {}
#gallery .previewText {
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 100px;
background: rgba(0,0,0,0.7);
color: #fff;
font: normal 12px arial;
padding: 10px;
}
#gallery .thumbnails {
float: left;
width:100px;
}
#gallery .thumbnails a, #gallery .thumbnails img {
display: block;
}
#gallery .thumbnails a img {
width: 100%;
opacity: .5; /* css standard */
filter: alpha(opacity=50); /* internet explorer */
}
#gallery .thumbnails a:hover img {
opacity: 1; /* css standard */
filter: alpha(opacity=100); /* internet explorer */
}
JS
$(function(){
var gallery = $("#gallery"),
thumbnails = gallery.find(".thumbnails a"),
previewImg = gallery.find(".previewImg"),
previewText = gallery.find(".previewText");
thumbnails.on("click", function(e){
var thumbImg = $(this).find("img");
previewImg.attr("src", thumbImg[0].src);
previewText.html(thumbImg[0].title);
});
});
I'd call the onclick from the image itself instead of adding the onclick via JS to the image.
You're doubling your work.
Where do you want the text to be displayed?
If it has to be displayed on top of the image, you'll have to make the image a background-image of a div or so.
If the text has to be above/under the image, place a span above/under the image and give it an ID.
Working with a span
JS:
function showBig(srcBig, title) {
var mainImg = document.getElementById('MainImg');
var mainText = document.getElementById('MainText');
mainImg.src = srcBig;
mainImg.title = title;
mainText.innerHTML = title;
}
HTML:
<div id="main">
<span id="MainText">Title will come here</span>
<img src="Default Img" alt="Big img's will come here" />
</div>
<img src="URL of thumbnail (e.g. smaller version)" alt="" onClick="showBig('URL of big version', 'Title')" />
Working with BG-image
JS:
function showBig(srcBig, title) {
var mainDiv = document.getElementById('MainDiv');
MainDiv.style.backgroundImage = srcBig;
MainDiv.innerHTML = title;
}
HTML:
<div id="MainDiv">
</div>
<img src="URL of thumbnail (e.g. smaller version)" alt="" onClick="showBig('URL of big version', 'Title')" />
By the way, you can ofc still add the onClicks via JS:
document.getElementById("yourImg").onclick = showBig('URL of Big', 'Title');
By the way, Don't use the same img for the thumbnails.
You'll probably use some big images which takes longer to load and then display it much smaller via CSS.
Make a smaller version (e.g. 100x100px or whatever size the thumbs should be) and only load the bigger version when the onClick is called.
Also, you better use a CSS-class like .thumbs to style the thumbs.
Otherwise you'll have to add a new ID to the list in your CSS file everytime you add a new image.
JSFiddle

Categories

Resources