This is more or less an icon on the page that when clicked does something, but the icon on the page is currently an anchor. I can change this to a div (all the rest of the icons are divs for that matter in my UI), but for some reason the following doesn't work.
Why does the first click register nothing?
$('#a').click(save);
function save(ev) {
$('#canvas')[0].toBlob((blob) => {
let URLObj = window.URL || window.webkitURL;
ev.target.href = URLObj.createObjectURL(blob)
ev.target.download = "untitled.png";
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id='canvas'></canvas>
<a id='a'>click me to save</a>
Fiddle to see behavior: https://jsfiddle.net/udbq3fb7/
Through much trial and effort, without using a 3rd party, here is an answer that works too:
$('#a').click(save);
function save(ev) {
$('#canvas')[0].toBlob((blob) => {
let URLObj = window.URL || window.webkitURL;
let a = document.createElement("a");
a.href = URLObj.createObjectURL(blob);
a.download = "untitled.png";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
}
fiddle: https://jsfiddle.net/rkqkr47w/
Here is a walk-through the current situation:
Now, what your code is trying to do is to overwrite the default behavior of the click (4.) action, by changing your <a>
's href
in the event handlers (3.).
This trick normally works, because 3. happens before 4., but in your case, you are calling an asynchronous method in 3., and the href
is only changed after your async callback gets called.
So you have
...
3. Canvas.toBlob(callback)
4. default click behavior happens
...
n. callback fires (change default behavior)
When your callback gets called, your click event is long dead, and changing its href
will have incidence only on the next click.
You could call directly the <a>
's click
method inside this callback, but it would lead to an infinite loop, except if you remove the event handler and reassign it again, but it would probably be easier to create a new <a>
element altogether, that you would remove afterward, and even easier to use a library like FileSaver.js which does exactly this along with handling some quirks in older browsers.
$('#a').click(save);
function save(ev) {
$('#canvas')[0].toBlob((blob) => {
saveAs(blob, "untitled.png");
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.js"></script>
<canvas id='canvas'></canvas>
<a id='a'>click me to save</a>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With