Get transfer speed of a file uploading though jquery/Ajax? - javascript

I am uploading a file through ajax/jquery. The demo can be found here. This function will output the percentage complete:
//progress bar function
function OnProgress(event, position, total, percentComplete)
{
//Progress bar
$('#progressbox').show();
$('#progressbar').width(percentComplete + '%') //update progressbar percent complete
$('#statustxt').html(percentComplete + '%'); //update status text
if(percentComplete>50)
{
$('#statustxt').css('color','#000'); //change status text to white after 50%
}
}
But how do I get the transfer speed?
When I printed all the variables of OnProgress, I had this:
event: [OBJECT XMLHTTPREQUESTPROGRESSEVENT]
position: 25668
total: 2122576
percentComplete: 2
I have tried to output event.speed but I got undefined.
I do not want calculate the transfer speed on the server-side, and use another ajax request polling simultaneously that returns the amount downloaded, it would not be efficient.

You could estimate it client side...
The easiest way would be to add a global variable in your javascript, for upload start times.
<script language=javascript>
var starttime = new Date().getTime();
function setStartTime(){
starttime = new Date().getTime();
}
</script>
and in the html
<input type="submit" id="submit-btn" value="Upload" style="display: inline-block;" onclick="setStartTime()"/>
then you will need to add some stuff like this:
//progress bar function
function OnProgress(event, position, total, percentComplete)
{
//Progress bar
$('#progressbox').show();
$('#progressbar').width(percentComplete + '%') //update progressbar percent complete
var timeSpent = new Date().getTime() - starttime ;
$('#statustxt').html(percentComplete + '% time spent so far:' + String(timeSpent)); //update status text
if(percentComplete>50)
{
$('#statustxt').css('color','#000'); //change status text to white after 50%
}
}
now you just need to use the position / timespent to calculate the average speed since beginning to now..

Related

ajax undefined after a thousand iterations

When creating an animation I try to use javascript for additional effects, namely snow being piled up and falling off the edges of the foreground. I figured that the javascript could do the "calculations" on a <canvas> that had the image, then send the "snow" to a php script that would create the png images. This is all placed on my local "server" because that is the only one that can write files.
<html>
<head>
<title>Making Snow</title>
</head>
<body bgcolor="black">
<canvas id="canvas" width="1920px" height="1080px"></canvas>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
var canvas;
var ctx;
var frame=-530;
var simg = new Image()
var dimg = new Image()
onload = function()
{
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
simg.src = "prodB/C/DGB.0530.png"
}
simg.onload = function()
{
var ipo=3;
// Initialize all pixels on the screen/page
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(simg,0,0);
document.title = "Making Snow " + (frame+530) + " / 7000";
snowdraw();
}
dimg.onerror = function()
{
dimg.src = "../imagewriting/snow" + zeroFill(frame+530,4) + ".png";
}
dimg.onload = function()
{
frame++;
if(frame<530)
simg.src = "prodB/C/DGB.0530.png"
else if(frame>4400)
simg.src = "prodB/C/DGB.4400.png"
else
simg.src = "prodB/C/DGB." + zeroFill(frame,4) + ".png"
}
var snowdraw = function()
{
var temp;
var canvasData = "";
// console.log(screen);
// Animation
// Choose a random pixel at the top of the screen
if(frame<7000)
{
for(ny=canvas.height-2; ny>=0; ny--)
{ // Iterate through all the pixels starting from the bottom right corner.
for(nx=canvas.width-2; nx>=0; nx--)
{
canvasData=canvasData+"1";
}
}
$.ajax({
method: "POST",
url: "makesnow.php",
data:{ imgData: canvasData, frame: (frame+530) }
})
.done(function( msg ) {
dimg.src = "../imagewriting/snow" + zeroFill(frame+530,4) + ".png";
});
}
else
{
document.title = "COMPLETE";
}
}
// http://stackoverflow.com/questions/1267283/how-can-i-create-a-zerofilled-value-using-javascript
// by Peter Bailey http://stackoverflow.com/users/8815
function zeroFill( number, width )
{
width -= number.toString().length;
if ( width > 0 )
{
return new Array( width + (/\./.test( number ) ? 2 : 1) ).join( '0' ) + number;
}
return number + ""; // always return a string
}
</script>
</html>
However, on the 1640th frame (or more precisely frame=1110) ajax is suddenly undefined. The image snow1640.png is created, but the browser tells me ajax is not defined and won't advance passed Making Snow 1640 / 7000. Because of the small random nature for each "snow flake" I can't just pick it up from where I left off, as the snow would jump from one frame to the next. Though I did try that at one point and ajax still stopped after that frame.
I first ran it on the local machine running Firefox (http://127.0.0.1/...) then moved onto another machine on the network which is more powerful running Chrome and both died on that same frame. Thought it might be a memory or file limit so I moved the complete frames out of there. Still nothing.
EDIT: Code now snippit of just the problem.
Also, console.log for data and ajax.responseText seem to be generally empty, both during successful "renders" and when it starts iterating ajax is not defined (every other line empty, every other error).
EDIT: New development! Turns out that the error ReferenceError: ajax is not defined anyways gets called between frames (and the 404 when asking dimg if image was created).
EDIT: By typing in console.log($.ajax) after onload and commenting out simg.src I got function ajax().
Error persists, this time I expanded it to reveal the following:
success http://127.0.0.1/ag/makesnowBC.html 197:7
j http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 2:27131
fireWith http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 2:27949
x http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 4:22242
b http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 4:26298
EDIT: Changed the code to now use Synchronous ajax. This time there are no error messages what so ever, but it still stops at 1640.

How to check upload speed in javascript?

Basically I have created a simple project where users can drag and drop to upload a file to server. Just to inform the user how long would it take to complete the process I need to show their upload speed. I found this question estimate users' upload speed without direct permission But It quite didn't suited my project.
So here is my code how i'm upload the file:
function upload(file){
var xhr=new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
alert(xhr.responseText);
}
}
xhr.upload.addEventListener('progress', function(e){
$('.upgbar').show();
$('.trkpb').css('width', (e.loaded/e.total*100)+"%");
var loaded = e.loaded;
var total = e.total;
var progressValue = Math.round( ( e.loaded / e.total ) * 100 );
var seconds_elapsed = ( new Date().getTime() - started_at.getTime() )/1000; var bytes_per_second = seconds_elapsed ? loaded / seconds_elapsed : 0 ;
var Kbytes_per_second = bytes_per_second / 1000 ;
var remaining_bytes = total - loaded;
var seconds = seconds_elapsed ? remaining_bytes / bytes_per_second : 'calculating' ;
$('.time_re').text("Time Remaining: "+seconds.charAt(0));
}, false);
xhr.open('post','../uploadtostack',true);
xhr.setRequestHeader('X-File-Name',file.name);
xhr.setRequestHeader('x-File-Size',file.size);
xhr.setRequestHeader('X-File-Type',file.type);
xhr.send(file);
}
through xhr.upload.addEventListener I can estimate the time remaining and the amount of data uploaded But don't know to munipulate this to show me the upload speed. and If you Might why am I getting an error at line $('.time_re').text("Time Remaining: "+seconds.charAt(0));
TypeError: seconds.charAt is not a function[Learn More]
I would really appreciate if someone could tell me how to implement a speechecker in javascript || jquery. Regards
You can try send a defined size file before and calculate the estimate time with this.
Example: demo file.txt > size 10k 1 second
another: filetoupload.txt > size 20k expected time 2 seconds

My script for page loading bar, returns differently everytime of F5

I got a free source progress bar, and I wrote a script for it.
the script is here,
var nanobar = new Nanobar( options );
var loaded = 0;
var number_of_media = $("body img").length;
doProgress();
// function for the progress bar
function doProgress() {
$("img").load(function() {
loaded++;
var newWidthPercentage = (loaded / number_of_media) * 100;
nanobar.go(newWidthPercentage);
document.getElementById("showing").innerHTML = newWidthPercentage;
})
};
});
This. I think,
Loaded <-- (which gets + 1 every time an image finished loaded)
divided by
Number of total body images,,
and then multiplied by 100
So that this can make the percentage number of loading process.
Then I put that percentage number into the box of,
A Loading bar's destination point. (which is : nanobar.go( here ))
But the bar moves werid,
everytime I click the menu, it returns different.
so I made a box to display the percentage number ( in the red box you can see in the picture )
I don't understand how this kind of random numbers are coming out every time.
Please advice.
Consider....
6/7 = 0.8571428571;
0.8571428571 * 100 = 85.71428571;
So if you want to 'tidy' these long decimals, then you need to truncate the float. http://www.w3schools.com/jsref/jsref_tofixed.asp
var num = 0.8571428571 * 100;
var n = num.toFixed(2);
Then n == 85.71
I hope this helps.

jQuery setinterval function change css

I want to make a function to change my background <header> every 5 seconds.
On the one hand I have an image that changes every X time, It is generated by a php file:
../bg.php
So I've done that I change the background-image with $("header").css().
Running the script like this:
(function($)
{
$(document).ready(function()
{
var $container = $("header");
$container.css("background-image", "url(bg.php)");
var refreshId = setInterval(function()
{
$container.css("background-image", "url(bg.php)");
}, 9000);
});
})(jQuery);
But does not change by itself.
This is just a guess, but there's a good chance that the browser is just caching the file. You could add cache control headers on the server, or else add a nonce parameter each time you change the background:
var counter = 1, refreshId = setInterval(function()
{
$container.css("background-image", "url(bg.php?_=" + counter++ + ")");
}, 9000);
It's probably a good idea to go ahead and set the cache headers properly anyway, just to avoid having client browsers needlessly cache the same image over and over again.
Maybe because your browser cache it. place a random number at the end of url:
$container.css("background-image", "url(bg.php?rnd=" + Math.random() + ")");
var refreshId = setInterval(function()
{
$container.css("background-image", "url(bg.php?rnd=" + Math.random() + ")");
}, 9000);
window.setInterval(function(){
/// call your function here
}, 5000);
You probably need to call location.reload(); as well.
Try to add query to bg.php
var d = new Date();
var n = d.getTime();
$container.css("background-image", "url(bg.php?" + n + ")");
the browser will not load the file with same name again
You're going to need to set the background-image to a different URL if you don't want to reload the entire page. However, you can attach a fragment (ex. http://example.com/index.php#fragment), or alternatively a query string (ex. http://example.com/index.php?querystring) to that URL .php file each time. If you are going to reset it every 5 seconds, a good method would be to append a new Date().getTime(); to the end of the image source URL, like this:
var currentDate = new Date();
$container.css("background-image", "url(bg.php#" + currentDate.getTime() + ")");
or even more succinctly/efficiently
$container.css("background-image", "url(bg.php#" + new Date().getTime() + ")");
You should end up with a background-image property of something like url(bg.php#1413320228120). This is good because the fragment won't affect where the browser looks for the image (still bg.php), but it'll consider it a different URL each time and load it again.
Your solution should look something like:
(function($)
{
$(document).ready(function()
{
var $container = $("header");
$container.css("background-image", "url(bg.php)");
var refreshId = setInterval(function()
{
$container.css("background-image", "url(bg.php)");
}, 9000);
});
})(jQuery);

JQuery progress bar pauses when browser tab is changed

I'm trying to display a progress bar on a html page using javascript. However,
when the browser tab containing the code becomes inactive, the progress bar stops updating,
being resumed when the tab is active again.
How can I prevent the browser from stopping/pausing the execution of javascript code when the window is inactive?
Although it may be irrelevant, here is the code:
Object.progressBar = function(){
$( "#question-progress-bar" ).progressbar({
value: false,
complete: function(event, ui) { ... }
});
var seconds = 15.0,
progressbar = $("#question-progress-bar"),
progressbarValue = progressbar.find(".ui-progressbar-value");
progressbarValue.css({
"background": '#c5b100',
"opacity" : '0.8'
})
var int = setInterval(function() {
var percent = (15-seconds)/15*100;
seconds=seconds-0.1;
progressbar.progressbar( "option", {
value: Math.ceil(percent)
});
$("#question-progress-bar-seconds").html((seconds).toFixed(1)+"s");
if (seconds <= 0.1) {
clearInterval(int);
}
}, 100);
}
Instead of using setInterval and assuming a certain amount of time has passed between calls (even when it's up front, setInterval has hit or miss accuracy) use the Date object to get a time when the bar starts, and compare that to the current time at each iteration.
<html>
<head>
<script>
function go()
{
var pb = new ProgressBar(5, "targ");
}
window.onload = go;
function ProgressBar(l, t)
{
var start = Date.now();
var length = l * 1000;
var targ = document.getElementById(t);
var it = window.setInterval(interval, 10);
function interval()
{
var p = 100 * (Date.now() - start) / length;
if(p > 100)
{
p = 100;
window.clearInterval(it);
alert("DONE"); // alternatively send an AJAX request here to alert the server
}
targ.value = (Math.round(p) + "%");
}
}
</script>
</head>
<body>
<input type="text" id="targ" />
</body>
</html>
I've made an example object, here, that immediately starts a countdown when instantiated and calls an alert and kills the interval timer when done. Alternatively an AJAX call, or any other sort of call can be done upon completion.
It should be noted that this will NOT complete the call if the browser stops Javascript all together. It will, however, complete it as soon as the tab has been given focus again if enough time has passed in the interim. There is no way for a website to alter this sort of browser behavior from the scripting side.
Hope that helps!

Categories

Resources