Конечно, это так (хотя у меня нет iPhone под рукой).
Проблема здесь в том, что загрузка Image является асинхронной задачей (она выполняется параллельно с JavaScript выполнением). ), даже если источником является data: URL, и вы не можете нарисовать изображение, которое еще не загружено на холст.
Теперь, почему это работает в некоторых браузерах? Потому что вы фактически выполняете чертежную часть тоже асинхронно , но в несвязанном событии.
Базовая структура немного сложна, но в основном FileReader всегда запускает два разных события, когда завершает чтение BLOB-объекта : onerror и onloaded или onload и onloadend , onloadend срабатывает сразу после предыдущего.
Здесь вы устанавливаете src
вашего <img>
в событии onload
, в этот момент браузер начнет загрузку изображения. Поскольку он основан на URL-адресе data: он не имеет большого значения (без сетевого запроса), поэтому, когда запускается второе событие ( onloadend ), оно может фактически уже загрузить изображение и, таким образом, может быть в состоянии нарисовать его на холсте.
Тем не менее, это на самом деле неудача, что он работает.
Правильный способ справиться с этим, это ждать onload
вашего изображения event.
reader.onload = function (e) {
img.onload = function () {
var canvas = document.createElement("canvas");
var width = img.width;
var height = img.height;
var ctx = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
var imgloc = document.getElementById("cardloc");
imgloc.appendChild(canvas);
};
img.src = e.target.result
}
reader.readAsDataURL(file);
Но вам даже не нужен FileReader, вам лучше использовать blob: URL , который является просто указателем на файл на диске и, таким образом, избегает напрасной траты памяти, а также избегает одного уровня ада обратного вызова:
img.onload = function () {
var canvas = document.createElement("canvas");
var width = img.width;
var height = img.height;
var ctx = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
var imgloc = document.getElementById("cardloc");
imgloc.appendChild(canvas);
}
img.src = URL.createObjectURL(file);
Ps: так как вы сказали, что также делаете обрезку, если после этого исправления у вас все еще есть проблемы с Safari, тогда я приглашаю вас прочитать это Q / A о фактической ошибке в этом браузере (что я не могу быть уверен, что вы столкнулись с тем, что вы нам здесь дали).