2014-02-19 2 views
2

Я знаю, что на это, возможно, ответили много раз, но я не знаю слов, чтобы найти ответ. Итак, вот вопрос.Получить переменную функцию внутренней загрузки

Я использую JavaScript и у меня есть

function getDataUrl(file){ 
    var url = URL.createObjectURL(file), 
    canvas = document.createElement('canvas'), 
    ctx = canvas.getContext("2d"), 
    img = new Image, 
    dataURL = ''; 

    img.load = function(){ 
     canvas.height = this.height; 
     canvas.width = this.width; 
     ctx.drawImage(this, 0, 0); 
     dataURL = canvas.toDataURL("image/jpeg"); 
    }; 

    img.src = url; 
    return dataURL; 
} 

затем на входе у меня есть это,

$('#file-input').on('change', function(e){ 
    var dataUrl = getDataUrl(e.target.files[0]); 
    console.log(dataUrl); 
}); 

Но возвращать пустую строку (начальный один). Я хочу, чтобы данные base64 уже сгенерировали внутреннюю загрузку.

Я попробовать что-то вроде этого

function getDataUrl(file){ 
//... codes 

    img.load = function(){ 
     //... codes 
     dataURL = canvas.toDataURL("image/jpeg"); 
     return dataUrl; 
    }; 
} 

но, конечно, она не может, так как он вернется к функции загрузки, а не его родителей функция.

Как получить dataUrl значение внутри функции загрузки?

Благодаря

+1

сделать вашу 'dataUrl' глобальной переменной, тогда ее значение будет разделяться между функциями. – muneebShabbir

+1

@muneebShabbir Извините, но это не так, по крайней мере, двумя способами: глобальные вары плохи по причинам, которые должны быть очевидны, и переменная не должна быть задана при ее доступе (она может быть *, но нет гарантии). – Carpetsmoker

+1

@Carpetsmoker да, вы правы, я неправильно понял поток кода, в этом случае обратный вызов будет единственным прекрасным решением – muneebShabbir

ответ

1

Ваш код, сокращенно, выглядит следующим образом:

function getDataUrl() { 
    dataURL = ''; 

    img.load = function() { 
     dataURL = 'Hello!'; 
    }; 

    return dataURL; 
} 

Что img.load = function делает ничего кроме правопреемника функция до img.load, выполнение будет просто продолжено с оператором return, что означает, что ваша переменная dataURL сохраняет исходное значение.
Вы должны понимать, что функции в Javascript van должны быть привязаны к переменным, как строка или число. Это не нужно выполнять.
Это может быть немного запутанным, это, безусловно, отличается от многих других языков, но вы получите его. Обязательно продолжайте читать &, узнав о javascript.

Возможно, вы захотите использовать img.onload, это будет выполнять функцию всякий раз, когда изображение будет завершено. Но это может быть всякий раз, когда, может быть, 1 секунда, может быть, 10, может быть, никогда.

Что вам нужно сделать, это что-то вроде:

$('#file-input').on('change', function(e) { 
    getDataUrl(e.target.files[0], function(dataUrl) { 
     console.log(dataUrl); 
    }); 
}); 

function getDataUrl(callback) { 
    dataURL = ''; 

    img.onload = function() { 
     callback(dataUrl); 
    }; 

    return dataURL; 
} 

Здесь вы передаете функцию в качестве аргумента, выполнить эту функцию после того, как изображение по окончании загрузки, передавая dataUrl в качестве параметра. Это довольно распространенный шаблон в Javascript.

+0

Да, это работа. Обратный звонок был идеальным решением. Я думал об этом раньше, но просто не знаю, как его применять. Благодарю. –

0

load событие является асинхронным. Это означает, что это произойдет когда-нибудь в будущем ПОСЛЕ завершения вашей функции getDataURL(). Таким образом, вы не можете вернуть нужное значение из функции getDataURL(), потому что изображение еще не загружено, а обработчик события загрузки еще не был вызван. Таким образом, вместо этого вам нужно думать асинхронно и программировать таким образом, чтобы с этим справиться. Типичный способ сделать это - передать функцию обратного вызова, которая будет вызвана, когда данные будут доступны, и вы можете передать эти данные функции обратного вызова.

Есть много различных способов кодировать, но вот один из способов:

function getDataUrl(file, callback){ 
    var url = URL.createObjectURL(file), 
    canvas = document.createElement('canvas'), 
    ctx = canvas.getContext("2d"), 
    img = new Image, 
    dataURL = ''; 

    img.load = function(){ 
     canvas.height = this.height; 
     canvas.width = this.width; 
     ctx.drawImage(this, 0, 0); 
     dataURL = canvas.toDataURL("image/jpeg"); 
     // pass the dataURL to the callback function 
     callback(dataURL); 
    }; 

    img.src = url; 
} 

getDataUrl("myfile.jpg", function(dataURL) { 
    // code here to use the dataURL   
}); 
+0

да, наконец, я кое-что узнал о том, когда применять обратный вызов. Благодарю. –

Смежные вопросы