My image hotel taking bit while as its trying to load large size image. How can I set an Ajax Loader GIF image before the actual image loads to make my users understand to wait. Thanks.
$(document).ready(function () {
window.showim = function(src) {
$("#imgLoader").attr("src", src);
};
});
JSFiddle: http://jsfiddle.net/52dY7/
The simpliest way is to start with a loader image in the source of the targeted image.
<img id="imgLoader" src="path/to/your/loader.gif" />
Look here...
http://jsfiddle.net/xflofoxx/52dY7/2/
$(document).ready(function () {
$('img').each(function() {
var $img = $(this),
origSrc = $img.attr('src');
$img.attr('src', '/path/to/loader/image');
$('<img />').on('load', function() {
$img.attr('src', origSrc);
}).attr('src', origSrc);
});
});
Related
I'm using a simple script to cause a deferred loading of all images on a page; the path for the image sources is contained in a data-src attribute and then put into the actual srcattribute of the img tag(s). Pretty much how most (?) implementations of the lazy loading method work.
Here's the script:
[].forEach.call(document.querySelectorAll('img[data-src]'), function(img) {
img.setAttribute('src', img.getAttribute('data-src'));
img.onload = function() {
img.removeAttribute('data-src');
};
});
I would like to use the same script for deferred loading of background images as well. How do I have to change it so that the data-src attribute ends up in the url-value of a div's background-image-property?
I tried the following with no results, because the script doesn't recognise background-image as a property:
[].forEach.call(document.querySelectorAll('div[data-src]'), function(div) {
div.setAttribute('background-image', div.getAttribute('data-src'));
div.onload = function() {
div.removeAttribute('data-src');
};
});
Problem may be with the background image as an attribute. Have you tried setting the style with the background image?
[].forEach.call(document.querySelectorAll('div[data-src]'), function(div) {
div.setAttribute("style","background-image: url(" + div.getAttribute('data-src') + ");");
div.onload = function() {
div.removeAttribute('data-src');
};
});
[].forEach.call(document.querySelectorAll('div[data-src]'), function(div) {
div.style.backgroundImage="url('" + div.getAttribute('data-src') + "')";
div.onload = function() {
div.removeAttribute('data-src');
};
});
Try this
I have this piece of code.
<img data-bind="attr: {src: 'imagePath'}, style: { 'background-image': 'url('imagePath')' }" class="img-responsive">
The problem is it is showing two images. One is the image coming from src and other one coming from background image. My goal was to enable the background image when the src image is not available.
What you can do is create a custom binding, let's call it safeSrc.
In this binding, you listen to the load and error events of your image - rendering your image if it's loaded successfully and rendering a fallback if it is not.
In practice, it could look like the following:
ko.bindingHandlers.safeSrc = {
update: function(element, valueAccessor) {
var options = valueAccessor();
var src = ko.unwrap(options.src);
$('<img />').attr('src', src).on('load', function() {
$(element).attr('src', src);
}).on('error', function() {
$(element).attr('src', ko.unwrap(options.fallback));
});
}
};
And then, you can apply the binding like this:
<img alt="Foo" data-bind="safeSrc: {src: imageObservable, fallback: 'https://example.com/fallback.png'}" />
Note that this presumes you're using jQuery - but you can easily rewrite the event listener.
Finally, I would also like to say that you should be rendering a different src instead of the background image - unless you have a specific reason to require one?
Either way, you can simply change the line $(element).attr('src', ko.unwrap(options.fallback)); to $(element).css('background-image', 'url(' + ko.unwrap(options.fallback) + ')');.
JS Fiddle Demo
Here, you can see it all in action: https://jsfiddle.net/13vkutkv/2/
(EDIT: I replaced the cheeky hotlink to the Knockout JS logo with Placehold.it)
P.S.: Depending on how you wish to interact with the element in future (interacting with/updating the binding), you may wish to use applyBindingsToNode (i.e. the Knockout-way), rather than manipulating the src attribute directly on the DOM element.
To show alternate image if img src is not found make alternate image link in your server logic and use only src: 'imagePath' in your front-end
Or if it is important to do it in front-end, you should look at this post:
Display alternate image
I always check my images with a deferred object to be sure they will load. This is using the jquery deferred method, but you could use any deferred library. I coded this from memory, so there may be some errors.
<img data-bind="attr: {src: $root.imagePath()}, style: { 'background-image': 'url('imagePath')' }" class="img-responsive">
var myController = function()
{
var self = this;
this.imagePath = ko.observable('myPath.png'); // Make the image url an observable
var getImagePath = function(path)
{
var imagePath = this.imagePath();
isLoaded(imagePath).done(function(result)
{
// The image will load fine, do nothing.
}).fail(function(e)
{
self.imagePath('defaultImageOnFail.png'); // replace the image if it fails to load
});
};
getImagePath();
};
var isLoaded = function(img)
{
var deferred = new $.Deferred();
var imgObj = $("<img src='"+img+"'/>");
if(imgObj.height > 0 || imgObj.width > 0)
{
deferred.resolve(true);
}
else
{
imgObj.on("load", function(e)
{
deferred.resolve(true);
});
imgObj.on("error", function(e)
{
console.info("VoteScreenController.isLoaded URL error");
deferred.reject();
});
}
return deferred.promise();
};
I want to show a low-res image and start loading the hi-res image after the complete page has rendered. Only when the hi-res image is completely loaded, I want to replace the low-res image by the hi-res image.
I know I should use
$(window).load(function(){
});
But what do I do to actually start loading a certain image? And how do I know when the image is loaded?
(I know about the existence of lazyload, but this image has to be the background of an element, so I have to use .css("background-image", var) and can't use lazyload I guess.)
Use this script to preload the images:
<div class="hidden">
<script type="text/javascript">
<!--//--><![CDATA[//><!--
var images = new Array()
function preload() {
for (i = 0; i < preload.arguments.length; i++) {
images[i] = new Image()
images[i].src = preload.arguments[i]
}
}
preload(
"images-1.png",
"images-2.png",
"images-3.png",
"images-4.png"
)
//--><!]]>
</script>
</div>
Then use low-res images in your html as you need and change to hi-res images when needed. The preloaded image is there for you.
$(window).load(function(){
$(selector).css('background-image',images[0]);
});
In your HTML
<img src='lowres.gif id='mypic'>
<script>
var img = document.getElementById("mypic");
var img2 = new Image();
var img2.onload = function() {
img.parent.insertBefore(img2, img);
// Or hide it.
img.style.display = "none";
};
var img2.src = XXXXX;
</script>
This code works, but is it an efficient way to go about displaying an image once it has been loaded?
LightBoxNamespace.SetupLightBox = function(path, lightBox) {
// Create a new image.
var image = new Image();
// The onload function must come before we set the image's src, see link for explanation.
// http://www.thefutureoftheweb.com/blog/image-onload-isnt-being-called.
// Anonymous function set to onload event, to make sure we only proceed if the image has been loaded.
image.onload = function () {
if ($('#image').length) {
$('#image').attr('src', path); // If the element already exists, change the src to our loaded image.
}
else {
$('<img id="image" alt="">').attr('src', path).insertAfter('#close'); // If the element does not exist, insert the full image html into the lightbox.
}
LightBoxNamespace.CentreBoxInViewport(lightBox);
LightBoxNamespace.ShowOverlay(lightBox);
};
// Set the src, and show the image.
image.src = path;
};
var img = $('<img>');
img.load(function(){alert("image loaded!")});
img.attr('src', "url");
if (!! img) img.appendTo('#close');
http://jsfiddle.net/W57QR/4/
"The jQuery way":
var $img = $('<img/>').prop({ src: path });
$img.load(function() {
console.log('image loaded correctly');
$(this).insertAfter('#close');
}).error(function() {
console.log('error loading image');
});
It's easy to keep javascript waiting for some images to load if those are classic HTML images.
But I can't figure how to do the same if the image is loaded as a CSS backuground-image!
Is it possible?
The jQuery .load() method doesn't seem to apply.. and I'm short of ideas
It looks for elements with src attribute or backgroundImage css property and calls an action function when theirs images loaded.
/**
* Load and wait for loading images.
*/
function loadImages(images, action){
var loaded_images = 0;
var bad_tags = 0;
$(images).each(function() {
//alert($(this).get(0).tagName+" "+$(this).attr("id")+" "+$(this).css("display"));
var image = new Image();
var src = $(this).attr("src");
var backgroundImage = $(this).css("backgroundImage");
// Search for css background style
if(src == undefined && backgroundImage != "none"){
var pattern = /url\("{0,1}([^"]*)"{0,1}\)/;
src = pattern.exec(backgroundImage)[1];
}else{
bad_tags++;
}
// Load images
$(image).load(function() {
loaded_images++;
if(loaded_images == ($(images).length - bad_tags))
action();
})
.attr("src", src);
});
}
One alternate approach would be to fetch the image data via AJAX as a base64 encoded png and apply it to the element's background-image property.
For example:
$.get('/getmyimage', function(data) {
// data contains base64 encoded image
// for ex: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==
$('#yourElement').css('background-image', 'url("' + data + '")');
});
You will also need a server side script that reads the image, converts it into base64 encoded png (and cache it maybe) and return the same.
Try this one...
Its a jQuery-Plugin which gives you control to wait for images to be loaded
Project-Home
Thread # SO
Official way to ask jQuery wait for all images to load before executing something
Answer # SO
(ShortLink)
this is untested code but try this:
$(document).ready(
function()
{
var imgSrc = $('theTargerElement').css('background-image');
var imgTag = $('<img>').attr('src',imgSrc).appendTo( 'body' );
}
);
$(document)
.load(
function()
{
// do stuff
}
);