2013-06-26 13 views
36

W tej chwili mam canvas i chcę go zapisać jako PNG. Mogę to zrobić za pomocą tych wszystkich skomplikowanych API systemów plików, ale tak naprawdę ich nie lubię.Pobierz obraz z JavaScript

wiem, czy istnieje związek z atrybutem download na nim:

<a href="img.png" download="output.png">Download</a> 

będzie pobrać plik, gdy użytkownik kliknie na nim. Dlatego wpadłem na to:

$("<a>") 
    .attr("href", "img.png") 
    .attr("download", "output.png") 
    .appendTo("body") 
    .click() 
    .remove(); 

Demo: http://jsfiddle.net/DerekL/Wx7wn/

Jednak to nie wydają się działać. Czy musi to być spowodowane działaniem użytkownika? Albo dlaczego to nie zadziałało?

+1

jestem przy założeniu, że używasz przeglądarki, która obsługuje to? http://caniuse.com/download – Ian

+1

@Ian używam Chrome i obsługuje go. –

+0

Nie wydaje mi się, że mogę użyć nazwy, którą podaję - czy możesz? – drzaus

Odpowiedz

64

Problemem jest to, że jQuery nie wyzwala rodzimą click imprezę dla <a> elementów, dzięki czemu nawigacja nie stanie (normalne zachowanie w <a>), więc trzeba to zrobić ręcznie. W prawie wszystkich innych scenariuszach wywoływane jest rodzime zdarzenie DOM (przynajmniej próbowano - jest w próbie/haczyku).

Aby uruchomić go ręcznie, spróbuj:

var a = $("<a>") 
    .attr("href", "http://i.stack.imgur.com/L8rHf.png") 
    .attr("download", "img.png") 
    .appendTo("body"); 

a[0].click(); 

a.remove(); 

DEMO:http://jsfiddle.net/HTggQ/

odpowiedniej linii w obecnym źródła jQuery: 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)) { 
+0

Czy można to umieścić w .each()? Mogę tylko pobrać jeden obraz za jednym razem, używając tej techniki, prawdopodobnie ma coś wspólnego z przeciążeniem zmiennej ... – bafromca

+5

[Nie sądzę, że musisz dołączyć/usunąć ją z DOM] (http: // jsfiddle.net/HTggQ/93/) - powinieneś po prostu zadzwonić '$ ('') .attr (...) [0] .click()' – drzaus

+2

lub [jeszcze lepiej, bez jquery] (http://stackoverflow.com/a/16523173/1037948) - http://jsfiddle.net/HTggQ/95/ – drzaus

32

Jak @Ian explained, problem jest to, że jQuery's click() nie jest tym samym, co macierzysty.

Dlatego należy rozważyć użycie wanilia-js zamiast jQuery:

var a = document.createElement('a'); 
a.href = "img.png"; 
a.download = "output.png"; 
document.body.appendChild(a); 
a.click(); 
document.body.removeChild(a); 

Demo

+19

Dlaczego spadł? Czy to dlatego, że istnieje [za mało jQuery] (http://i.stack.imgur.com/sGhaO.gif)? – Oriol

+3

Podtrzymuję twój komentarz i twoją odpowiedź. Downvotes bez wyjaśnień nie są pomocne. –

+2

Dzięki @Oriol. Lubię wanilię! –