I can't validate tag img - javascript

this is Augusto from Italy
when migrating from HTML to XHTML I am facing an unresolved problem
In html code I have an image (bigimg) that is at first charged via Js charged by the body onload, then other images, out of a preview series, are being charged, thus replacing my image,
In body:
<body onload="...........;viewimgac('images/accessories/img01cs.jpg');...............">
The function is:
// the waiting image view and the main image loading is managed
function elaboraimgac(urlimg) {
document.getElementById('dattesa').style.filter = "alpha(opacity:"+90+")";
document.getElementById('dattesa').style.MozOpacity = 90/100;
document.getElementById('dattesa').style.KHTMLOpacity = 90/100;
document.getElementById('dattesa').style.opacity = 90/100;
MM_changeProp('dattesa','','style.visibility','visible','LAYER'); // div is made visible through the waiting gift.
document.getElementById('bigimgid').src = urlimg; // I load the image
The code page shows:
<img src="#" id="bigimgid" style="position:absolute;left:0px;top:0px;" onload="finecaricimg()" alt="" />
the <img> tag, as it is, prevents XHTML validation. I have to eliminate onload="finecaricimg()", being the function allowing view of image duly placed in the page using the image size that is available after loading.
I acted this way:
1) change <img tag
<img src="#" id="bigimgid" style="position:absolute;left:0px;top:0px;" alt="" />
2) I added :
function elaboraimgac(urlimg) {
//to Js elaboraimgac function
//........
//........
document.getElementById('bigimgid').onload = finecaricimg(); // the specific function is called after loading
}
To intercept the image loading end and recall the loading end function
Unfortunately the procedure is unsuccessful. Via alert I realized that the image size – when the loading end is charged – is zero, as if finecaricimg() is charged right after the .src processing and not when the image loading is over.
I tried to add:
document.getElementById('bigimgid').src = urlimg;alert("AAAAA"); // load image
then, when the alert window appears, I wait for some seconds before clicking OK. This way the image size is correct and the image is properly placed in the page.
I am unable to understand, as the code seems the correct one.
I am therefore asking for your suggestion.

....onload = finecaricimg();
You just called your function immediately and assigned its result to onload (just like any other function call).
You want to assign the function itself, without calling it.

I have solved in this way:
var img = document.getElementById("bigimgid");
img.src = urlimg; // carico l'immagine
img.addEventListener("load", finecaricimg); // a fine caricamento richiamo la funzione specifica
thanks

Related

Javascript / jQuery: Detect when each individual image loads

I'm creating a loading bar for my website and I want to update the loading progress (%) with each image load. For testing purposes, I used console.log() (instead of updating my loading bar).
I want to detect when each individual image loads. My images are all within <div id='images>
I have not found a solution that has worked after 5 hours of searching. I'm new to jQuery & Javascript, so I may have been using incorrect syntax (such as not targetting the image container correctly, but I'm not sure.
I have tried the imagesloaded jQuery plugin, but when using $('#images').imagesLoaded(), imagesloaded had said that all images had loaded, when they hadn't. (I'm testing using two 4k images so I can see the images slowly load).
The imagesloaded jQuery code I used for testing (loadProgress.js):
$('#images').imagesLoaded() //My images are within "<div id='images></div>"
.always( function( instance ) {
console.log('all images loaded');
})
.done( function( instance ) {
console.log('all images successfully loaded');
})
.fail( function() {
console.log('all images loaded, at least one is broken');
})
.progress( function( instance, image ) {
var result = image.isLoaded ? 'loaded' : 'broken';
console.log( 'image is ' + result + ' for ' + image.img.src );
});
// Code I used to keep track of when the page actually loaded
console.log('Page load started')
window.onload = function() {
console.log('Page load complete')
My HTML (Images were for testing purposes only and may be copyright) [just a snippit, not including doctype, body etc]:
<script src="https://unpkg.com/imagesloaded#4/imagesloaded.pkgd.min.js"></script>
<script scr="loadProgress.js"></script>
<div style="text-align:center" id="images">
<img src="https://wallpapers.gg/wp-content/uploads/2018/01/Old-Lion-4K.jpg" alt="Lion 4K" id='image' />
<img src="https://images7.alphacoders.com/383/383230.jpg" alt="Lion 4K" id="image" />
</div>
Console output [comment]:
Page load started
all images loaded
all images successfully loaded
[a good 5 second delay]
Page load complete
The output looks promising as the images are said to load after the page load has begun, but there is a 5 second delay between all images successfully loaded and Page load complete where I can see the images slowly render top-to-bottom and can also see the spinning loading icon in my browser tab (indicating that the images have not loaded yet, as there is no other html to load). I believe that the plugin is not correctly detecting the images container.
How can I (preferably automatically, not having to assing a unique ID to each image, and for them to collectively be found) detect when each individual image has loaded?
I'd like my console output to be (for example with two images):
Page load started
Image loaded
Image loaded
[no delay]
Page load complete
I am not looking to detect when all images have been loaded, and specifically want to repeat an action each time an image is loaded. In this case, the action would be console.log('Image loaded')
Using either Javascript or jQuery isn't a problem, and if you know a plugin which can achieve this more efficiently, I'd love to know.
I am not sure about the jQuery plugin you are using, but you could register an "onload" function to each image you want to load. No additional plugins/libraries needed, plain JavaScript should be fine.
Ideally, you would do it on backend side, not frontend, since images might be already loaded (think of browser cache) at the moment you assign the "onload" function.
If you want to target every image, just use the $('img') as your selector. If not, target their container element an you should be good to go.

Image.onload event triggers apears to trigger before image is loaded

I have a function that displays a different image each time it is called.
function Trial() {
curTrial = increase(curTrial);
//generate the html code
$('#right_wrapper').append(`
<div id="image_holder">
<img id="image">
</div>`)
// present the image
var targetImage = document.getElementById('image')
targetImage.src = stimuli[curTrial];
console.log(targetImage.onload = targetImage.height)
The way i though onload works is that it will not trigger until the src is loaded, but it seems to trigger anyway, and thus result the 0 height for the unloaded image. I've found more threads with similar issues, but none of those I've seen work with template literals.
How can i be sure that targetImage.height always returns the height for the loaded image, instead of 0?

Why is my div not updating when changing its class with JavaScript?

I currently have a div that's used to display and image via CSS.
For example:
HTML
<div id="myDiv" class="play"></div>
CSS
.play{background: url('../img/playIcon_black.png') no-repeat;}
This image appears as it should.
What I'm attempted to do is to change the image by changing the class (via JavaScript).
Example:
CSS
.pause{background: url('../img/pauseIcon_black.png') no-repeat;}
JavaScript
function myFunction() {
myDiv.className = "pause";
}
When I call myFunction() everything seems to work correctly with one exception. Occasionally the image does not update in the browser.
A few things to note:
I'm certain the function is being called correctly. If I put a console.log() statement within the function, it prints when it should. Additionally, if I inspect the element within the browser, the class is in fact changed to .pause
The image changes from the "play icon" to blank once the function is called, BUT upon hovering over the div the images then appears permanently.
This only seems to happen once the page is initially loaded. Meaning, I can only recreate the issue once upon refresh, then everything works correctly after that.
I have attempted to clear my cache but nothing seems to have changed.
(I'm not sure how relevant this is) I'm calling myFunction() via onended attribute of an audio tag.
For example:
<audio onended="myFunction()"></audio>
But I'm not certain if this would affect anything because the function appears to be called correctly.
Any ideas of why this might be happening?
So the issue is that when you change the class, the browser has to fetch the new image, which takes time. One way to fix the issue is by using sprites, where both images are actually in one image and you only show a piece of that image at a time.
Another solution is to preload the image and then apply the preloaded image source to your new element like this:
var image = newImage();
image.src = '../img/pauseIcon_black.png';
function myFunction() {
var cssBackground = 'url(' + image.src + ') no-repeat';
myDiv.style.background = cssBackground;
// Optionally with jQuery instead:
// $('#myElementID').css('background', cssBackground);
}
Note that if you call myFunction before the image loads you'll encounter the same error. The difference is that this will load the image when the page is loaded (or more properly, when this JS executes and myFunction is assigned) rather than when myFunction is called. To ensure the image is loaded you can use the onLoad event handler for the image object. For more details on preloading images check out this answer: preload image then change background javascript
You need to get the element id
function myfunction(){
var myDivElem = document.getElementById('myDiv');
myDivElem.className = 'pause';
}
You can use document.getElementById("myDiv").className="";in your function
OK if you don't want use first solution you can use second one:
You can add a class to element using
document.getElementById("myDiv").className +=" n";
Then add a class named .play.n to your css file after class named.play
Then add your image address.
If you want to manipulate the div with id "myDiv". Use it as
document.getElementById('myDiv').class
Sample codesnippet: example snippet

Placeholder while an image is loading with Ember.js [duplicate]

I'm currently working on a web application which has a page which displays a single chart (a .png image). On another part of this page there are a set of links which, when clicked, the entire page reloads and looks exactly the same as before except for the chart in the middle of the page.
What I want to do is when a link is clicked on a page just the chart on the page is changed. This will speed things up tremendously as the page is roughly 100kb large, and don't really want to reload the entire page just to display this.
I've been doing this via JavaScript, which works so far, using the following code
document.getElementById('chart').src = '/charts/10.png';
The problem is that when the user clicks on the link, it may take a couple of seconds before the chart changes. This makes the user think that their click hasn't done anything, or that the system is slow to respond.
What I want to happen is display a spinner / throbber / status indicator, in place of where the image is while it is loading, so when the user clicks the link they know at least the system has taken their input and is doing something about it.
I've tried a few suggestions, even using a psudo time out to show a spinner, and then flick back to the image.
A good suggestion I've had is to use the following
<img src="/charts/10.png" lowsrc="/spinner.gif"/>
Which would be ideal, except the spinner is significantly smaller than the chart which is being displayed.
Any other ideas?
I've used something like this to preload an image and then automatically call back to my javascript when the image is finished loading. You want to check complete before you setup the callback because the image may already be cached and it may not call your callback.
function PreloadImage(imgSrc, callback){
var objImagePreloader = new Image();
objImagePreloader.src = imgSrc;
if(objImagePreloader.complete){
callback();
objImagePreloader.onload=function(){};
}
else{
objImagePreloader.onload = function() {
callback();
// clear onLoad, IE behaves irratically with animated gifs otherwise
objImagePreloader.onload=function(){};
}
}
}
You could show a static image that gives the optical illusion of a spinny-wheel, like these.
Using the load() method of jQuery, it is easily possible to do something as soon as an image is loaded:
$('img.example').load(function() {
$('#spinner').fadeOut();
});
See: http://api.jquery.com/load-event/
Use the power of the setTimeout() function (More info) - this allows you set a timer to trigger a function call in the future, and calling it won't block execution of the current / other functions (async.).
Position a div containing the spinner above the chart image, with it's css display attribute set to none:
<div> <img src="spinner.gif" id="spinnerImg" style="display: none;" /></div>
The nbsp stop the div collapsing when the spinner is hidden. Without it, when you toggle display of the spinner, your layout will "twitch"
function chartOnClick() {
//How long to show the spinner for in ms (eg 3 seconds)
var spinnerShowTime = 3000
//Show the spinner
document.getElementById('spinnerImg').style.display = "";
//Change the chart src
document.getElementById('chart').src = '/charts/10.png';
//Set the timeout on the spinner
setTimeout("hideSpinner()", spinnerShowTime);
}
function hideSpinner() {
document.getElementById('spinnerImg').style.display = "none";
}
Use CSS to set the loading animation as a centered background-image for the image's container.
Then when loading the new large image, first set the src to a preloaded transparent 1 pixel gif.
e.g.
document.getElementById('mainimg').src = '/images/1pix.gif';
document.getElementById('mainimg').src = '/images/large_image.jpg';
While the large_image.jpg is loading, the background will show through the 1pix transparent gif.
Building on Ed's answer, I would prefer to see something like:
function PreLoadImage( srcURL, callback, errorCallback ) {
var thePic = new Image();
thePic.onload = function() {
callback();
thePic.onload = function(){};
}
thePic.onerror = function() {
errorCallback();
}
thePic.src = srcURL;
}
Your callback can display the image in its proper place and dispose/hide of a spinner, and the errorCallback prevents your page from "beachballing". All event driven, no timers or polling, plus you don't have to add the additional if statements to check if the image completed loading while you where setting up your events - since they're set up beforehand they'll trigger regardless of how quickly the images loads.
Some time ago I have written a jQuery plugin which handles displaying a spinner automatically http://denysonique.github.com/imgPreload/
Looking in to its source code should help you with detecting when to display the spinner and with displaying it in the centre of the loaded image.
I like #duddle's jquery method but find that load() isn't always called (such as when the image is retrieved from cache in IE). I use this version instead:
$('img.example').one('load', function() {
$('#spinner').remove();
}).each(function() {
if(this.complete) {
$(this).trigger('load');
}
});
This calls load at most one time and immediately if it's already completed loading.
put the spinner in a div the same size as the chart, you know the height and width so you can use relative positioning to center it correctly.
Aside from the lowsrc option, I've also used a background-image on the img's container.
Be aware that the callback function is also called if the image src doesn't exist (http 404 error). To avoid this you can check the width of the image, like:
if(this.width == 0) return false;
#iAn's solution looks good to me. The only thing I'd change is instead of using setTimeout, I'd try and hook into the images 'Load' event. This way, if the image takes longer than 3 seconds to download, you'll still get the spinner.
On the other hand, if it takes less time to download, you'll get the spinner for less than 3 seconds.
I would add some random digits to avoid the browser cache.

Pre Load images to display later on click event jQuery

I have a web page where lots of images called from server using image
scr attribute.
I have created a function like which is triggered by td click.
function GoToStep(stepNo) {
var imgSrc = $("#h1" + stepNo).val();
$(".img_vertical").css("background-image", "url(" + imgSrc + ")");
}
Now the problem is this. For slower connections the images come after some
moment.
Can I pre load images to avoid waiting time when user clicks
td?
I have seen some jquery function to pre load images.
Kindly give some idea how can I achieve it.
Pre-loading an image is equivalent to loading an image but never displaying it. So, you can easily do it like this:
<img src="image.png" alt="" style="display:none;"/>
Now this image will be loaded as soon as the html starts rendering. Whenever you need to use this image as a display or background, just set the address to image.png and it will automatically be fetched from browser's cache.
This can be done using some javascript functions. Quoting from another question.
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
// Alternatively you could use:
// (new Image()).src = this;
});
}
// Usage:
preload([
'img/imageName.jpg',
'img/anotherOne.jpg',
'img/blahblahblah.jpg'
]);
Explanation of how javascript preloaders work (different question)
[...] The way it works is simply by creating a new Image object and setting
the src of it, the browser is going to go grab the image. We're not
adding this particular image to the browser, but when the time comes
to show the image in the page via whatever method we have setup, the
browser will already have it in its cache and will not go fetch it
again. [...]
So in your case, you should use something like
$(function() {
// Do stuff when DOM is ready
preload([
'img/bg1.jpg',
'img/bg2.jpg',
'img/bg3.jpg'
]);
});

Categories

Resources