I have an HTML button with an onclick function "clicked()".
If clicked I want to load an image as "background-image" of a div tag.
The image shall be loaded from a server that serves the image very unreliable (rain-radar),
very high answer time up to timeout. I have no control of the server but I am allowed
to fetch the image.
If the image cannot be loaded or is not loaded after 30 seconds I want to show either a failover image or a simple text message to try again later.
I tried to define a second (failover) image url to the style background-image attribute but
then my page always loads the failover image and I guess that's not how it works. Also I dont want to show a "loading image failed" image while page still waits to receive an answer...
index.html
...
GoToDiv
...
javascript:
function clicked(){
document.getElementById('gotoDiv').style.backgroundImage = "url('https://UNRELIABLE.SERVER/pic.jpg'), url('/failover.jpg')";
}
I there a proper way to do that?
You can try a preloading technique
function clicked() {
var elem = document.getElementById('gotoDiv');
elem.style.backgroundImage = 'url("loading.gif")';
function setErrorImg () {
elem.style.backgroundImage = 'url("failover.jpg")';
}
var timer = window.setTimeout(setErrorImg, 30000);
var img = new Image();
img.onload = function() {
window.clearTimeout(timer);
elem.style.backgroundImage = 'url("' + img.src + '")';
};
img.onerror = setErrorImg;
img.src = 'https://UNRELIABLE.SERVER/pic.jpg';
}
Related
I have a Python websocket application which sends an image path to a JavaScript HTML file. When the image path is received, I change the background image of the webpage to the supplied image.
The issue I'm having at the moment, is when the background changes from the old image to the new, there is a momentary 'flash' of which, which suggests that there is a period of time (albeit very brief) where the new image is being loaded.
I've tried various preloading methodologies, but I'm very new to JavaScript, so am not sure which method would provide for a seamless transition between the two images. This is the method I currently have implemented:
var NewImage = new Image();
NewImage = message.data; //This is the image string received from Python
document.body.style.backgroundImage = "url('" + NewImage + "')";
The above displays the image as desired (including my CSS formatting), but the transition is unsightly.
I also had a play around with the following method, which makes more sense to me, but I couldn't get it to work.
var NewImage = new Image();
//Websocket function here
PreloadImage;
function PreloadImage() {
NewImage.onload = ImageLoadComplete();
NewImage.src = message.data;
}
function ImageLoadComplete() {
document.body.style.backgroundImage = "url('" + NewImage + "')"
}
I'm not sure how to pass variables between the functions in this second method. Given the explicit 'onload' call in this method, I feel that this may provide the functionality I'm after.
How can I preload the images in order to seamlessly transition between them?
EDIT: The working code is posted below. Thanks to #blender for pointing me in the right direction :)
var NewImage = new Image;
NewImage.src = message.data; //Data from Python
if (NewImage.complete) {
NewImage.onload = ImageLoadComplete();
} else {
NewImage.onload = ImageLoadComplete;
}
function ImageLoadComplete() {
document.body.style.backgroundImage = "url('" + NewImage.src + "')";
}
You're not actually passing a callback function:
NewImage.onload = ImageLoadComplete();
You're passing in the result of calling ImageLoadComplete(), which means you call your callback immediately. Don't call the function and your code should work as expected (most of the time):
NewImage.onload = ImageLoadComplete;
One issue that you'll encounter is that onload may not get called by some browsers if the image is loaded from cache. You have to call the callback manually if that's the case:
if (NewImage.complete || NewImage.height > 0) {
ImageLoadComplete();
} else {
NewImage.onload = ImageLoadComplete;
}
Hello I want to fadeOut image, and then do fadeIn with a new one, so I wrote a simple code, but something goes wrong, because when .photo img fadesOut, then fadesIn this same photo, but after, a few second its changes because of new "src", but even if browser didn't load a new image, the old one shound't show, becuase src is changed, but it shows, and after a second, maybe two changes to the new one. Can somebody tell me what's wrong?
var dimage = $next.children("img").attr("rel");
$(".photo img").fadeOut("slow", function () {
$(".photo img").attr("src", dimage);
$(".photo img").fadeIn("slow");
});
This may be because the image has to load after the src is altered.
Consider putting the image in a tag, then setting the css property to display:none. This way the image will preload in the browser before your script runs and will be available when it does.
you aren't giving the new image enough time to load.
function loadImage (src) {
return $.Deferred(function(def){
var img = new Image();
img.onload = function(){
def.resolve(src);
}
img.src = src;
}).promise();
}
var dimage = $next.children("img").attr("rel");
var imageLoadedDef = loadImage(dimage);
$(".photo img").fadeOut("slow", function () {
def.done(function(src){
$(".photo img").attr("src", src);
$(".photo img").fadeIn("slow");
});
});
the problem as highlighted is about images not ready for display when you call them, so the solution is to preload them before starting the slideshow, create a function with an array of images path
function preLoad(){
var imgs = {'test1.jpg', 'test2.jpg', 'test3.jpg'};
var img = document.createElement('img');
for(var i = 0; i < imgs.leght; i++){
img.src = imgs[i]; //all images gets preloaded at this stage
}
startSlider(); //here you will do your code
}
Is it possible to restart a gif animation without downloading the file every time?
My current code looks like this:
var img = new Image();
img.src = 'imgages/src/myImage.gif';
$('#id').css('background-image', 'url("' + img.src + '?x=' + Date.now() + '")' );
Edit
When I insert the gif into the dom it didn't restart the gif animation. I can only achieve this by appending a random string to the image src but this will download the image again.
I want to know if it is possible to restart the gif animation without downloading the gif.
I've had similar requirement.
var img = document.createElement("img"),
imageUrl = "http://i73.photobucket.com/albums/i231/charma13/love240.gif";
img.src = imageUrl;
document.body.appendChild(img);
window.restartAnim = function () {
img.src = "";
img.src = imageUrl;
}
for example on facebook - animated emoticons are not .gifs but a set of static frames on png file with dynamically set background offset. This way you have full control over your animation from javascript - you can even pause/unpause it or change its speed.
It's possible to split your .gif file into separate frames and generate a .png file on server side dynamically.
This looks like a good weekend project for me ;)
restartGif(imgElement){
let element = document.getElementById(imgElement);
if (element) {
var imgSrc = element.src;
element.src = imgSrc;
}
}
// Example:
restartGif("gif_box")
function refreshgif() {
var giffile = $(".gif-class");
giffile.src = giffile.src;
}
I had a similar problem and I solved it by adjusting the image's display attribute before restarting the gif. Also, set the timeout to make sure that the restarting the gif will run after the image attribute is changed.
const img = document.getElementById("gif");
img.style = "display: none;";
img.style = "display: block;";
setTimeout(() => {
img.src = img.src;
}, 0);
This is inspired by this answer.
Just make it loop forever? otherwise you could use an ajax request every (duration of gif) to restart it.
even with javascript it would be possible;
var gif
window.onload=function () {
gif=document.getElementById('id')
setInterval(function () {
gif.src=gif.src.replace(/\?.*/,function () {
return '?'+new Date()
})
},5000)//duration of your gif
}
This may help you,
var img = new Image();
src = 'imgages/src/myImage.gif';
img.src=src;
$('body').append(img);
setInterval(function(){
t=new Date().getTime();
$("img").attr("src", src+'?'+t);
},5000);
create a function in javascript and then reput the image in the same place. when you want to replay the Gif call this function.
function replayGif(){
var img = new Image();
img.src = 'imgages/src/myImage.gif';
$('#id').css('background-image', 'url("' + img.src + '?x=' + Date.now() + '")' );
}
The simplest javascript solution:
Function:
function restartGif(ImageSelector){
var imgSrc=document.querySelector(ImageSelector).src;
document.querySelector(ImageSelector).src=imgSrc;
}
Call function:
restartGif(SELECTOR) // Example: restartGif('.homer')
Example: http://jsfiddle.net/nv3dkscr/
Try to set the src of the gif animation to itself or set it to an empty string followed by the original src again. ;)
I'm creating a big page with a lot of blocks containing big background images, so I thought the best thing would be to show a preloader and load images in the background and update the loader (image 4 of 20, ecc). My problem is: when the onload event fires my loader diasppears but I still see the image loading, this means it wasn't completely loaded. Why does this happen? any idea?
here's the page:
http://zhereicome.com/experiments/statics/myascensor/#1-1
Thanks in advance
nImages = $('.slide').length;
loadedImgs = 0;
var bgImages = ['img/bbb.png','img/bbb2.png','img/bbb3.png'];
$('.slide').each(function(i){
var curSlide = $(this);
var img = new Image();
img.src = bgImages[ i % 3 ];
img.onLoad = imageLoaded(img, curSlide);
})
function imageLoaded(img, curSlide){
curSlide.css('backgroundImage', 'url(' + img.src + ')');
loadedImgs++;
if(nImages == loadedImgs){
$('#container').css('visibility','visible');
$('#loader-cont').fadeOut(1000);
}
$('.loader-inner .title').text(loadedImgs / nImages);
}
You seem to have some trouble with window.onload and document.ready:
$(document).ready(function(){
// This will be executed when the DOM is ready.
});
$(window).load(function(){
// This will be executed when the whole document and all its
// referenced items (style sheets, scripts, images, etc.) are loaded.
});
But this has been asked before and answered much, much better: How can I create a "Please Wait, Loading..." animation using jQuery?
i call on a PHP script that generates graph images for me, however, it takes a few seconds. Is there a way to detect when it has finished loading, on the user side, and only swap it with the old image when the php script has finished and the image is ready?
here is the Javascript function i use to call the PHP script:
EDIT (CODE UPDATED)
function loadGraph(self,graph,varID) {
var img = new Image();
img.onload = function() {
$(self).parents().parents().siblings(".graph_container").empty().append(img);
};
img.src = 'drawGraph.php?type=journey_report&graph=' + graph +
(varID != null ? '&varID=' + varID : '') + '&companyID=<?php echo $_SESSION['companyID'] ?>';
}
and here is the graph container and the link that uses that function:
<div class="graph_container">
<img src="drawGraph.php?type=journey_report&graph=outOfDate_vs_upToDate&companyID=<?php
echo $_SESSION['companyID'] ?>" />
</div>
<div class="reportItemWrapper">
<div class="reportItem"><b>Total</b></div>
thanks!
Create an Image object and set its "onload" handler to a function that does what you do in that first block of code. Then set its "src" attribute to your URL.
var img = new Image();
img.onload = function() {
// that jQuery stuff
};
img.src = "drawGraph.php?type=journey_report ...";
Now that'll only work if the URL is cacheable. If not, then you could re-work that jQuery code so that you just stuff the Image element into the DOM.
$(self).parents().parents().siblings(".graph_container").empty().append(img);
(You'd still do that in the onload handler.)