Reputation: 94409
Right now I have a canvas
and I want to save it as PNG. I can do it with all those fancy complicated file system API, but I don't really like them.
I know if there is a link with download
attribute on it:
<a href="img.png" download="output.png">Download</a>
it will download the file if the user clicks on it. Therefore I came up with this:
$("<a>")
.attr("href", "img.png")
.attr("download", "output.png")
.appendTo("body")
.click()
.remove();
Demo: http://jsfiddle.net/DerekL/Wx7wn/
However, it doesn't seem to work. Does it have to be trigger by a user action? Or else why didn't it work?
Upvotes: 68
Views: 260666
Reputation: 288680
As @Ian explained, the problem is that jQuery's click()
is not the same as the native one.
Therefore, consider using vanilla-js instead of jQuery:
var a = document.createElement('a');
a.href = "img.png";
a.download = "output.png";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
Upvotes: 98
Reputation: 50933
The problem is that jQuery doesn't trigger the native click
event for <a>
elements so that navigation doesn't happen (the normal behavior of an <a>
), so you need to do that manually. For almost all other scenarios, the native DOM event is triggered (at least attempted to - it's in a try/catch).
To trigger it manually, try:
var a = $("<a>")
.attr("href", "https://i.sstatic.net/L8rHf.png")
.attr("download", "img.png")
.appendTo("body");
a[0].click();
a.remove();
DEMO: http://jsfiddle.net/HTggQ/
Relevant line in current jQuery source: https://github.com/jquery/jquery/blob/1.11.1/src/event.js#L332
if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
jQuery.acceptData( elem ) ) {
Upvotes: 84