Here is a walk-through the current situation:
- User clicks.
- Event gets dispatched in the document.
- EventHandlers fire [if any].
- default click behavior happens [if not prevented in 3.].
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>