jquery load image into div strange behaviour - javascript

I've made slideshow with thumbnails at it's side.
Here, basically a div which displays the image and after clickimg on a particular thumbnail, it's related picture will be dynamically displayed in the main div (#display #slideshowpic). Here is the code example,
<div id="container">
<div id="display">
<img id="slideshowpic" src="initial.jpg">
</div>
<div id="thumbs">
<img class="thumb" id="image1">
<img class="thumb" id="image2">
<img class="thumb" id="image3">
<img class="thumb" id="image4">
<img class="thumb" id="image5">
</div>
</div>
And here is the javascript,
$('.thumb').click( function() {
$('#slideshowpic').attr('src',""); /// clears or removes current image
$('#slideshowpic').attr('src',"/uploads/" + $(this).attr('id') + ".jpg");
});
Here, the image which is to be loaded in the main div after clicking thumbnail, is progressive image which is interlanced with php gd.
This is working perfectly in firefox. After clicking thumbnail, the image instantly displays in the main div with progressive fasion. But it doen't seems to be working in chrome.
The Problem is (chrome) : After clicking the thumbnail; first the image is cleared as per the code, then the previous image displays instead of new image (clicked image) and then new image displays after taking some time delay (i think the delay is the time which new image is taking to load).
google chrome doesn't show image till it loads image fully
I just can't figure out where is the problem is. Should i use another technique to load that dynamic image.. ? please help. I stucked in it from many days.
EDIT : you can check it in below links,
http://bit.ly/ZxVCM3
http://bit.ly/1oeutK5
http://bit.ly/1rIxvAV
Click the thumbnails to load the slideshow.

Seems like firefox uses the image cache and chrome doesn't.
I have used magnific popup,
http://dimsemenov.com/plugins/magnific-popup/
It has a built-in prefetch for galleries.

<img> without src has no reason...
$('.thumb').click( function() {
var img = $('#slideshowpic');
var src = $(this).attr('id');
img.css('opacity','0').on('load', function() {
$(this).fadeIn();
}).attr('src',"/uploads/" + src + ".jpg");
});
from Detect image load

Try this method:
img = new Image(); // this is important
img.src = src; // new src for the image.
img.onload = function () {
//Your logic. Replace the original image with the new one.
};
Instead of modifying the src of the image, try replacing the img tag with the new one when the new image is loaded. This should work for you. The issue is mainly because of the caching in chrome.

Related

Have background images of a carousel lazy-load and not be considered essential for UX purposes

I have a simple carousel on my home page. It changes pictures automatically after a couple of seconds. The html looks like this:
<div>
<div id="img-1" class="carousel-image" style="display: block;"></div>
<div id="img-2" class="carousel-image" style="display: none;"></div>
<div id="img-3" class="carousel-image" style="display: none;"></div>
</div>
I use a javascript function to add the images as background-image. To make sure the carousel images are all loaded before the carousel starts changing automatically I use new Image() and count the number of loaded images. Once all three images are loaded I can do startCarousel().
var numberOfLoadedImages = 0;
function setImage(imgUrl, imgId){
var homeImage = document.getElementById(imgId);
homeImage.style.backgroundImage = 'url(' + imgUrl + ")";
var img = new Image();
img.onload = function() {
if(numberOfLoadedImages === 2){
startCarousel();
}
numberOfLoadedImages++;
}
img.src = imgUrl;
if (img.complete) {
img.onload();
}
}
I can then simple call this function like this:
setImage('img-1', 'img-1');
setImage('img-2', 'img-2');
setImage('img-3', 'img-3');
What I would like to achieve is to lazy-load the second and third image. These two are not necessary at first page load; only the first image is important. Google Page Speed Insights mentions the second and third under the heading "Serve images in next-gen formats", whereas, if you ask me, they should not be considered part of the page. They should be loading in the background and they are really not essential for the first display and UX.
How can I tell the browser (or Google Page Speed Insights) that these images are completely non-essential for UX purposes and should not be considered part of the first paint and UX?
I tried putting the second and third call in a timeout with a short interval, but that didn't do the trick.
NB: I am using vanilla javascript; no plugins at all.
You can wait for everything to load and once the page is fully loaded (including images, etc.) you can run setImage for your second and third image.
document.addEventListener('DOMContentLoaded', function() {
setImage('img-2', 'img-2');
setImage('img-3', 'img-3');
}, false);
In case Google Page Speed Insights still registers this and prolong the initial page load time you can use async function to call setImage.

Loading an image with jQuery after clicking a Link

I would like to load an image from a Link:
1) Click on "a href", extract image url from href/src/id
2) Link should dissapear and show Ajax-Loader Image while loading Image.
3) Display loaded image.
If it's possible i dont want to use any buttons or div-constructs to output image - only a simple link.
On Click:
<a class="loc" href="./misc/images/image1.png"></a>
Browser should output an image:
<img src="./misc/images/image1.png" />
so far i made this:
$('a.loc').text('load image').css("cursor","pointer");
$('.loc').click(function(){
$(".loc").fadeOut(300);
$(".loc").html('<img src="/images/ajax-loader.gif" />');
var image = $(this).attr('src');
*** how to show/load image, how to use my var ??? ***
});
Has anybody an idea how to complete this task? I'm, greatful for any help.
You may use replaceWith:
var image = $(this).attr('src');
$(this).replaceWith('<img src="'+ image +'">');
However your method to show a loading image will not work more. You should add some prefetching logic to your codes and use replaceWith after fetching image.

Control which image loads first

I'm wondering if there is a way to control which image loads first when the user opens the website. The problem is that I have a simple one-page website that is taking too much time to open the first image (Big Home image - example). I would like to load this image first, and then load the other images in the website, should I do it manually with Jquery for each image (using $.attr("src") after document.ready)? or is there a better way?
Control which image loads first
If you want to have control over which images to load first and load the images synchronously then try this. Working JsFiddle
var loaded = 0;
var imgSrcArray = ["https://upload.wikimedia.org/wikipedia/commons/thumb/4/49/Small_icosihemidodecahedron.png/100px-Small_icosihemidodecahedron.png",
"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d9/Small_cubicuboctahedron.png/100px-Small_cubicuboctahedron.png",
"https://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Small_dodecahemidodecahedron.png/100px-Small_dodecahemidodecahedron.png",
"https://upload.wikimedia.org/wikipedia/commons/thumb/a/ad/Small_rhombicuboctahedron.png/100px-Small_rhombicuboctahedron.png"];
$('div img').on('load',function(){
loaded++;
var indexOfThisImg = imgSrcArray.indexOf($(this).attr('src'));
$('#output').append("loaded image " +indexOfThisImg + '<br/>');
loadNextImg(loaded);
});
function loadNextImg(index){
$('div img:eq('+index+')').attr('src',imgSrcArray[index]);
// if the imag tags are not continuous and you want to load the images in random position in an order then you can maintain the order of the images in a separate array and then use that indexes to load the images.
}
$('div img:eq(0)').attr('src',imgSrcArray[0]);
//trigger the load of first image, which starts the chain reaction
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<img />
<img />
<img />
<img />
</div>
<div id="output">
</div>
The idea is to hold all the images src in an array and load the first image, and on the load event of the image increment the array index and load the second one and so on.. This way we have control on the order of the images that should load. let me know if this helps

On a Web page - How to show a (light) image and replace it with a (heavy) one when the latter is downloaded by client?

I'm a beginner front-ender considering the following scenario :
A certain HTML page should include a heavy image (e.g - animated gif) but I don't want to force the client to sluggishly wait for it to completely download before enjoying a pretty page, rather I would prefer to show him a lightweight image (e.g - the first frame of the gif) and when the former is readily downloaded by the client's browser, replace the light one with the heavy.
What should be the best approach for the matter - Am I looking for a technological solution or a methodological one?
Thanks!
You can embed the light-weight image using a data-URL. This will show that image immediately.
<img src="data:image/gif;base64,---Your-Base64-Encoded-Image-Here---" />
You can use this web site to convert an image file to a data-URL.
What you then need to do is to load the larger image in the background and, once loaded, make it replace the light-weight image.
<img src="data:image/gif;base64,---Your-Base64-Encoded-Image-Here---" />
<img class="heavy" src="http://server.com/path/to/heavy/weight/image.gif" />
The following CSS hides the heavy-weight image initially:
/* Don't show heavy-weight images until they're loaded */
img.heavy {
display: none;
}
The following jQuery-based javascript will hide the light-weight image and show the heavy-weight image once it is loaded:
$(function () {
// Register handler that will be invoked when a heavy-weight image is loaded
$("img.heavy").on("load", function () {
// Hide the light-weight image
// (we assume that it is the immediate previous 'img' sibling of the
// heavy-weight image)
$(this).prev("img").hide();
// Show the heavy-weight image
$(this).show();
});
});
Update (not using data-URL)
If you don't want to use data-URL for the light-weight image, you can use a similar approach where you don't start loading the heavy-weight image until the light-weight is loaded.
<img class="light" src="http://server.com/path/to/light.gif" />
<img class="heavy" data-src="http://server.com/path/to/heavy.gif" />
The heavy-weight image is not loaded initially because it does not have a src-attribute.
The following script will start loading heavy-weight images (by copying data-src to src) as soon as the light-weight image is loaded, and finally "replace" the light-weight image once the heavy-weight image is loaded.
$(function () {
// Register handler that will be invoked when a light-weight image is loaded
$("img.light").on("load", function () {
// Start loading heavy image (by assigning the src-attribute)
$(this).next("img.heavy").each(function () {
$(this).attr("src", $(this).attr("data-src"));
}).on("load", function () {
// Show the heavy-weight image and hide the light-weight image
$(this).show().prev("img.light").hide();
});
});
});
Update 2 (automatic creation of heavy-weight image element)
If you can derive heavy-weight URLs from light-weight URLs, then you can use another approach which might be easier to use and maintain.
<img class="light" src="img/light/image.gif" />
The following script will create a new heavy-weight image element for each light-weight image that is loaded. The heavy-weight image URL is copied from the light-weight image URL, but with the text light replaced by heavy.
$(function () {
// Register handler that will be invoked when a light-weight image is loaded
$("img.light").on("load", function () {
// Create heavy-weight image element after the light-weight image
// URL is computed from light weight image (by replacing 'light' with 'heavy')
// The element is initially hidden.
$("<img/>")
.attr("src", $(this).attr("src").replace("light", "heavy"))
.hide()
.on("load", function () {
// Show the heavy-weight image and remove the light-weight image
$(this).show().prev("img.light").remove();
})
.insertAfter(this);
});
});
This version also removes the light-weight image from the DOM once the heavy-weight image is loaded.
I may use another simple solution depend on a hidden iframe for the heavy image. It will replace the src of the light image when the iframe is loaded. The iframe src will be the src of the heavy image.
<html>
<head>
<script>
function replaceImg(imgId,ifrId){
ifr = document.getElementById(ifrId);
img = document.getElementById(imgId);
img.src = ifr.src;
}
</script>
</head>
<body>
<img id="img1" src="../img/initializing.png" />
<iframe id="ifr1" onload="replaceImg('img1','ifr1')" src="http://lorempixel.com/800/400" style="display:none"></iframe>
</body>
</html>
A live DEMO is found here. However, if you could not able to notice the light image, press RUN button again in the jsfiddle page.

Create live preview of image (before upload it) using JQuery

I want to create a preview for image before upload it on the server, using JQuery.
My code, js code:
$(function(){
Test = {
UpdatePreview: function(obj){
// if IE < 10 doesn't support FileReader
if(!window.FileReader){
// don't know how to proceed to assign src to image tag
} else {
var reader = new FileReader();
var target = null;
reader.onload = function(e) {
target = e.target || e.srcElement;
$("img").prop("src", target.result);
};
reader.readAsDataURL(obj.files[0]);
}
}
};
});
My html:
<input type='file' name='browse' onchange='Test.UpdatePreview(this)' />
<br/><br/>
<img src="#" alt="test" width="128" height="128" />
See jsfiddle: http://jsfiddle.net/aAuMU/
After onload, I see the src of image (using Google console application) and it looks like:
data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD//gAEKgD/4gv4SUNDX1BST0ZJTEUAAQEAAAvoAAAAAAIAAABtbnRyUkdCIFhZWiAH2QADABsA...
It is a way to get in javascript the base of image and assign to image in case I'm using IE as browser ?
FileReader doesn't work in IE < 10.
If you need it as getting nice effect then you could use flash like they do in
https://github.com/mailru/FileAPI
But when i needed to show image to user because i needed to let user select area for croping then i used form inside hidden iframe and uploaded image to server and sent back image data uri so i was able to get data uri and replace image src attribute, then when area was selected i did not send image back as file but as data uri. In old browsers it means you upload image twice, but i did not want to use flash as in some cases flash may also not be installed there.
LIVE PREVIEW CAN BE DONE IN JQUERY
We need an onchange event to load the image. img tag is given an id = frame, the function UpdatePreview() loads the image immediately after the image or file is selected.
function UpdatePreview(){
$('#frame').attr('src', URL.createObjectURL(event.target.files[0]));
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<input type='file' name='browse' oninput='UpdatePreview()'/>
<img src="#" id ="frame" alt="test" width="128" height="128" />
Instead of
$("img").prop("src", target.result);
write
$("#ImageId").attr("src", target.result);
Where ImageId is the ID of your img tag.

Categories