executing code after download starts - javascript

I would like to add an animated loader image, which would appear after the user triggers downloading of an attachment, and disappear after the download actually starts - when the browser starts downloading the file (or displays the download confirmation dialog). The reason for it is that the attachments are quite complex documents generated on the server side, which takes some time and an animated loader would reassure the user that the page is working (and disable the download button until the download starts).
The attachment has properly set Http headers.
Here is what it looks like now:
var link = $("#download-link");
link.click(function () {
link.displayLoader();
$(document).load(link.attr("href"), function () {
link.hideLoader();
});
return false;
});
The main problem is that the load method obviously doesn't do what I would like to achieve. Is there a way to capture the actual start of downloading, triggered by window.location change?

You can do is.
Disable the whole screen until the Download is ready ( the server side processing).
And the user clicks a button download and the user directly downloads the file.
Approaches followed by most of the downloading website.
eg. Mediafire.com
PS: Disable the whole screen mean a System type dialog. disabling other options.

Why don't you show the loader image first?
If I understand correctly now, the problem is that you want the loader image to disappear once the file begins to download, and at present it disappears once the file has finished downloading?
I don't think there's an easy way to do it with jQuery, but if you drop down to using the normal JavaScript XMLHttpRequest object directly, you will get several callbacks at various stages of downloading that you can access through the readyState property.

Related

Dropzone upload in background (PHP)

I'm trying to upload multiple large files at once with Dropzone. I want to do so in asynchronous way.
It means, when I drop the files into Dropzone I want all of them to start uploading right away and at the same time I want to be able to leave the page (while uploading still continues).
When I drop multiple files now, they start to upload, but I cannot change the page immediately - the browser is waiting for the first file to be uploaded, then it finally goes to another page.
Is it possible to do the above with Dropzone? Is there some other way how to do this in PHP? Thank you.
I want all of them to start uploading right away and at the same time
I want to be able to leave the page (while uploading still continues).
Leave the page while uploading isn't possible.
A solution would be to use a singe page application, so you have never to reload the hole page. If you only change the content, it is possible to sill upload the content.

How to reload base64 animated GIF?

I use base64 animated GIF on my web page, when I try to reload page GIF still show last frame. How can I reload GIF from its beginning?
I tried use JS to clear innerHTML and then assign it back to my base64 GIF, but nothing happened.
I am also using C# and CefSharp (tried use Refresh() and chromeBrowser.GetBrowser().Reload()), would be great to get any tips how to make GIF play from its beginnig.
I use base64 because I cannot store image on users hard drive or Web, but I need to put this image into HTML, which can be loaded by CefSharp using C#. If there are any other ways to use animated image in HTML without storing it on HDD or web, please give me some tips too.
Update:
I decided to leave base64 because big size of my gifs (>25 Mb) cause lags and problems with reload.
I use CEFSharp v55-pre01 and found new problem.
What do I have:
Main menu
Form 1 (with cefsharp browser, which loads gif by code automatically)
Form 2 (with cefsharp browser, loads same gif)
From main menu I call Form 1, when Form 1 initialize, Form 1 create hidden Form 2.
First form initialize Cef
if (!Cef.IsInitialized)
{
Cef.Initialize(settings);
}
Each form in constructor initialize own browser
chromeBrowser = new ChromiumWebBrowser("");
Controls.Add(chromeBrowser);
Problem appear in situation, when I close second form (no mater is 2nd form shown or not) and dispose both forms and call Cef.Shutdown(). When I try open back first form from menu my app crashes.
Error appear at second form constructor on line chromeBrowser = new ChromiumWebBrowser(""); with such text:
An unhandled exception of type 'System.AccessViolationException'
occurred in CefSharp.Core.dll
Additional information: Attempted to read or write protected memory.
This is often an indication that other memory is corrupt.

Is it possible to serve up a different file than the intended one to be downloaded via JavaScript?

At work they want to do this to prevent people from downloading images easily from our site. They won't go the disable right click option, so they want to do what Flickr is doing:
http://www.flickr.com/photos/scg/12332332454/sizes/l/
If you right click and try to download that image it downloads the entire html page instead. Can this be done via JS or is it something handled by the server?
I know all this goes against usability and doesn't actually prevent people from ripping off images but it's what the ticket I'm assigned asks for.

Does changing the src attribute of an image stop the image from downloading?

Let's say that I have two accordion tabs. The first one loads hundreds of images and is open when the page loads.
I want to be able to stop the images from downloading if the user clicks on the second accordion tab. Will changing the src attributes of the images via js stop the images from downloading? Or do the requests just continue until completion and not show up on the page?
I have a script that loads the SO logo in exactly 3 seconds that I had made for another question.
http://alexturpin.net/slowimage/slowimage.php
Using it, I tried to reproduce the problem:
var img = new Image();
img.onload = function() {
alert("loaded");
};
img.src ="http://alexturpin.net/slowimage/slowimage.php";
setTimeout(function() {
img.src = "";
}, 1000);
http://jsfiddle.net/Xeon06/RrUvd/1/
From what I gather, in Chrome, the onload doesn't get fired, but the browser keeps on showing a spinner and if I go on the network tab and find my image and check it's content, it's there. So my answer would be no, the image still loads, at least in Chrome.
This is an interesting problem, I suggest you try and test it in as many browsers as possible and write some kind of blog post on it.
Your browser asks for that image with a specific HTTP GET request, as
specificated in HTTP protocol. Once it asks for it, the http server
starts the transfer.
So, it is between the browser (as http client) and the http server.
Since http protocol does not takes into account the option to abort a
transfer, the browser should implement a out-of-standard mechanism to
programmatically abort the connection. But since this is not specified
in any standard, i think you won't find any way to do that with
javascript or any client side code.
You can try window.stop() to stop all requests, but not individual
ones.
If you wanted to stop a single request for a large image, what you
could do is load the image into a document within a hidden IFRAME. The
onload event of the IFRAME can be used to load the image into the main
document, by which time it ought to be cached (presuming you have the
caching directives configured to do so).
If the image is taking too long, then you can access the IFRAME's
contentWindow and issue a stop command to that.
You need to have as many IFRAME elements as there are images that can
be requested simultaneously.
Taken directly from here & here.
Not sure if it will, just like the other comments. But I can suggest am approach that will work well. Assuming not all the images are visible, just set the right src attribute when they become visible.
So default the url to myGray.gif when it is not visible and set it to myImage.jpg when it does come into view.
When you close the current accordion, you can set the image source back to your lightweight gif again. (this prevents a bug related with gc on some versions of the ipad).

Detecting whether or not file has been served to the browser?..kinda

I have a button which sets window.location to a php file which generates a feed which is then downloaded. However, as the files vary in size due to what data is put into the feed it can sometimes take a while from the click of the button to the file dialog popping up.
What I would like to be able to do is click the button and display a loading.gif until the dialog / file is complete.
Any ideas would be cool!
Cheers
I'm not really sure why you need to check the size of the file at all? If you use ajax to dynamically do the get/post, and all you are doing is trying to show a loading icon while this is happening, its fairly simple to throw up an asynchronous activity indicator. For instance, with jquery:
$("#loading").ajaxStart(function(){
$(this).show();
});
$("#loading").ajaxStop(function(){
$(this).hide();
});
$("#feeds").load("feeds.php?id=89734258972347895");
The above code sets a DOM object with id "loading" to show and hide when any asynchronous request has been initiated and stopped. .load(url) loads the content of the url into the div #feeds. If you are setting the content-disposition: attachment header with php, it will automatically initiate a file download window, even though it has been loaded asynchronously into a div. This is also possible without jquery of course, there's just a bunch of browser compatibility javascript and its not as easy as simply subscribing to the ajaxStart and ajaxStop events to show and hide your loading img.
Josh
before setting window.location you could display a hidden div with your gif
It's old school, but this can be done very easily with server push
<?php
$separator = "end_of_section_marker";
header('Content-type: multipart/x-mixed-replace;boundary=$separator');
print "\n--$separator\n";
print "Content-type: text/html\n\n";
// Send placeholder message here
print "--$separator\n";
ob_flush();
flush();
// Start long processing here
print "Content-type: text/html\n\n";
// send data here
print "--$separator--\n";
?>
Just adjust the content-types for the data you're sending. $separator can be any value so long as it does not appear in the data being sent.
A method I've used in the past works like this...
Set window.location to a loading page, and pass the destination page in the querystring. The loading page should display an animated gif or whatever you prefer to demonstrate that processing is taking place. The loading page should IMMEDIATELY redirect to the destination page passed in the querystring (along with any other applicable querystring parameters).
EDIT: The loading page should redirect to the destination page using javascript (set window.location to the URL provided in the querystring). This is an important point, because if you redirect on the server-side the loading page won't get displayed.
EDIT 2: If your loading page is a php file, you can check the to-be-downloaded file's size and display an estimated download time to the user (along with an animated "loading" gif), or whatnot.
The destination page should render with buffering enabled (call ob_start() before you render any content). With buffering enabled, nothing is sent to the browser until the entire page is rendered. Meanwhile your loading page from step 1 will continue to be displayed.
Just make the RSS generating script show image you want (output image's HTML, then flush output buffer and start data generation). At the end of the data generation do:
<?php
print '<script>window.location = "http://www.newlocation.com"</script>'
That's all.
You will have to use AJAX to communicate to the server to discover the exact size of the file you are downloading. Then you have something to test against. There is no way to know the size of the expected payload from the client side only.
Is it possible for you to use an iframe to load the feed and then check the readyState of the iframe/document using an interval? So the process would be:
Load a window containing an iframe of width and height 100% and a loading.gif over the iframe.
Set a timer checking for the iframe.contentWindow.document.readyState property
Once readyState == complete, show the save file dialog.
One downside is, for most browsers the PHP file would need to be on the same domain (on IE you can just check the readyState property of the iframe).

Categories