I have been trying to preload images in pure Javascript following the ideas of Mark Meyer in https://www.photo-mark.com/notes/image-preloading/, which is exactly what I need.
The function I use is:
function preload(index) {
index = index || 0;
if (index < 10) {
preImage[index] = new Image();
preImage[index].onload = function() { preload(index+1) };
preImage[index].src = "img/IMG" + ("0000"+(index+1)).slice(-4)+"A.png";
};
return;
}
I want to preload images IMG0001A.png through to IMG0009A, in that order. preImage is an empty array.
My problem is that when I see the network activity in Chrome devtools, even though I simulate a slow connection and the cache is disabled, the images show a size of 0 bytes, and, of course, they are 'loaded' just too fast. Can anybody tell me what's going on? thanks in advance
Here is a screenshot of devtools:
Related
I am stuck on some point. Please help me to figure it out.
When any peer connection (In Video Conferencing) is disconnected and I reconnect them, then a blank frame is added in Recording, I am using RecordRTC and testing it in Chrome 74.0
I think it is happening because When Peer Connection is disconnected then the RecordRTC already have the previous connected data Video Elements, And I just want to remove those blank Elements.
I am attaching the screenshot of Recorded Video please help me to figure it out.
Here in this image, you can see we There are 5 Screens, In which 2, 3, 4 are blank,
Because the Peer Connection is closed and reconnected.
So I want these 2 Working Screens(1, 5) [ 1= Local Stream, 5 = Remote Stream] in my blob or we can say which Recording.
Please help me to figure it out this issue.
Thank you
Please use this solution,
We just need to give the condition to drow the first and last element on the canvas.
Update this code in function drawVideosToCanvas() .
var videosLength = videos.length;
if(videosLength > 2){
videosLength = 2;
}
var fullcanvas = false;
var remaining = [];
var length = videos.length;
videos.forEach(function(video,idx) {
if (!video.stream) {
video.stream = {};
}
if (video.stream.fullcanvas) {
fullcanvas = video;
} else {
if(idx==0 || idx == (length-1)){
if(video.stream.active)
remaining.push(video);
}
}
});
I have an HTML5 audio player and I'm trying to monitor it's buffering progress until it reaches 100% so I can run it.
music = document.querySelector("#music");
progress = document.querySelector("#progress");
music.addEventListener("progress", function(){
var z = (music.buffered.end(0) / music.duration)*100;
progress.value = z;
}, false);
(Where #progress is an HTML <progress> element.)
When I attempt the above code, I get this error.
Uncaught IndexSizeError: Failed to execute 'end' on 'TimeRanges': The index provided (0) is greater than or equal to the maximum bound (0).
This error has been discussed here, but the code I am using is similar to the code used in the answer, and I am still getting the error.
Here's the weird part: I monitored music.buffered.length, and it only reached 1 when the audio was fully loaded, so for some reason I cannot monitor the buffered length of my audio element.
Here's a rather robust JS Bin to show the problem.
Has anyone else run into this problem? Am I doing something completely wrong here?
You can get buffered value in loadeddata listener:
audio.addEventListener ('loadeddata', function () {
if (typeof (this.buffered) !== 'undefined' && this.buffered.length > 0) {
audio.addEventListener ('progress', function () {
var z = (this.buffered.end (0) / this.duration) * 100;
progress.innerText = z;
});
}
});
keep in mind that it inherits this, not music!
Years down the line, I managed to determine the problem. #dandavis was correct. My server was not supplying metadata about audio files, so the browser had no clue how long an audio file was (or even how big the file was in size) until it was completely downloaded. There was no timerange because there was no information about time supplied at all.
If you're having this problem, make sure your server is supplying EVERYTHING about your audio file.
you might want to try and replace this part:
music.addEventListener("progress", function(){
var z = (music.buffered.end(0) / music.duration)*100;
progress.innerText = z;
}, false);
with this part:
if(music.onprogress){
var z = (music.buffered.end(0) / music.duration)*100;
progress.innerText = z;
};
I am loading a large number of images into a dynamic DIV and I am using a preloader to get the images.
imageObj = new Image();
imageObj.src = imgpath + imgname;
Each of these events creates a GET that I can see and monitor in Firebug.
If I know the name and path of an image, can I watch the relevant XMLHttpRequest to see if the GET has completed?
I do not want to rely on (or use) .onload events for this process.
The pseudo would look something like this...
if (imageObj.GET = 'complete')
Has anyone had any experience of this?
EDIT 1
Thanks to the help from Bart (see below) I have changed my image preloader to store an array of the image objects...
function imagePreLoader(imgname) {
images[imgnum] = new Image();
images[imgnum].src = imgpath + imgname;// load the image
imgnum ++;
}
And then, after all my other functions have run to build the content DIVs, I used the image.complete attribute in the following...
var interval = setInterval(function () {
imgcount = imgnum - 1; // because the imgnum counter ++ after src is called.
ok = 1;
for (i=0; i<imgcount; i++) {
if (images[i].complete == false){
ok = 0;
}
}
if (ok == 1) {
clearInterval(interval);
showIndexOnLoad();
}
}, 1000);
This waits until all the images are complete and only triggers the showIndexOnLoad() function when I get the 'ok' from the interval function.
All images now appear as I wanted, all at once with no additional waits for the GETs to catch up.
Well done Bart for putting me on to the image.complete attribute.
You can watch the complete property of the image to see if the image is fully loaded or not.
Here's an example.
http://jsfiddle.net/t3esV/1/
function load (source) {
var img = new Image();
img.src = source;
console.log('Loading ' + source);
var interval = setInterval(function () {
if (img.complete) {
clearInterval(interval);
complete(img);
}
}, 400);
};
function complete(img) {
console.log('Loaded', img.src);
document.body.appendChild(img);
};
Note: This example fails to clear the interval when something goes wrong and complete is never set to true.
Update
I wrote a simple jQuery.preload plugin to take advantage of the image.complete property.
This is a very interesting problem, and I am afraid there is no actual solution to this. The load event for images is when the image is being rendered and the browser knows the width and height of it.
What you would be after would be a tag-applicable readystatechange event. Alas, only IE allows you to bind those to non-document elements, so this is not an option.
There are a bunch of plug-ins that allow you to go around it, as well. One pretty hot one is https://github.com/desandro/imagesloaded , which has the added advantage of dealing with all the browser differences very efficiently. It, however, still relies on the load event (and I am pretty sure this is the only way to start doing what you want to do).
Use Firefox 10.0.2 to open Framework.html from this project: http://code.google.com/p/unitspeeds-vhh/ (EDIT: I'm now preloading the icons. Use this revision if you'd like to try to debug the original problem.)
Hit F5 to refresh.
Hit F5 a few more times very quickly.
Expected: The unit icons (unitIconObj in the code) should always render.Actual: They never render on the first page load. First F5 usually shows all icons. Some very fast repetitions of F5 cause most most -- but not all -- icons to show.
The basic problem I'm trying to solve is icons not rendering properly the first time, and I assume this means I need to be preloading the images. I've been trying a few different methods to do this, but the behavior is not strictly reproducible, and I think I just don't know enough about refreshes and caching to figure this out myself. The icons themselves are very small image files, so I'm surprised to see that this is an issue at all.
Very sorry for the messy code and question -- I'm a noob! Any advice would be welcome.
Edit: Here's the part where I load the image file and render it:
for (var x = 0; x < sortedOutput.length; x++)
{
// Draw the unit icon
var unitIconObj = new Image();
if (sortedOutput[x].Filename == "--") // I don't have real icons for a few units
{
unitIconObj.src = "Icons/Creep.jpg";
} else
{
unitIconObj.src = "Icons/" + sortedOutput[x].Filename + ".jpg";
}
speedContext.drawImage(unitIconObj, ChartBuffer+textBlock+2+4*iconSpace, 50+(x*iconSpace), BarHeight, BarHeight);
}
Have you tried changing this so it waits to call drawImage function until the onload event on the image fires. This will ensure that the image is loaded before any of the other magic happens.
for (var x = 0; x < sortedOutput.length; x++)
{
var unitIconObj= new Image();
unitIconObj.onload = function(){
speedContext.drawImage(unitIconObj, ChartBuffer+textBlock+2+4*iconSpace, 50+(x*iconSpace), BarHeight, BarHeight);
};
if (sortedOutput[x].Filename == "--") // I don't have real icons for a few units
{
unitIconObj.src = "Icons/Creep.jpg";
} else
{
unitIconObj.src = "Icons/" + sortedOutput[x].Filename + ".jpg";
}
}
found this here: https://developer.mozilla.org/en/Canvas_tutorial/Using_images
Searching for a js script, which will show some message (something like "Loading, please wait") until the page loads all images.
Important - it mustn't use any js framework (jquery, mootools, etc), must be an ordinary js script.
Message must disappear when the page is loaded.
Yeah an old-school question!
This goes back to those days when we used to preload images...
Anyway, here's some code. The magic is the "complete" property on the document.images collection (Image objects).
// setup a timer, adjust the 200 to some other milliseconds if desired
var _timer = setInterval("imgloaded()",200);
function imgloaded() {
// assume they're all loaded
var loaded = true;
// test all images for "complete" property
for(var i = 0, len = document.images.length; i < len; i++) {
if(!document.images[i].complete) { loaded = false; break; }
}
// if loaded is still true, change the HTML
if(loaded) {
document.getElementById("msg").innerHTML = "Done.";
// clear the timer
clearInterval(_timer);
}
};
Of course, this assumes you have some DIV thrown in somewhere:
<div id="msg">Loading...</div>
Just add a static <div> to the page, informing user that the page is loading. Then add window.onload handler and remove the div.
BTW, what’s the reason of this? Don’t users already have page load indicators in their browsers?
You should do async ajax requests for the images and add a call back when it's finished.
Here's some code to illustrate it:
var R = new XMLHttpRequest();
R.onreadystatechange = function() {
if (R.readyState == 4) {
// Do something with R.responseXML/Text ...
stopWaiting();
}
};
Theoretically you could have an onload event on every image object that runs a function that checks if all images is loaded. This way you don´t need a setTimeOut(). This would however fail if an image didn´t load so you would have to take onerror into account also.