【问题标题】:Input onchange javascript function call not working in Safari输入 onchange javascript 函数调用在 Safari 中不起作用
【发布时间】:2016-12-04 13:18:44
【问题描述】:
我有一个 html 画布,当在输入中选择图像时,它会显示图像的预览。这适用于 Chrome,但我似乎无法让它在 Safari 中运行。具体来说 - 在 Safari 中 - onchange="previewFile()" 似乎没有调用 previewFile 函数。
<canvas id="canvas" width="0" height="0"></canvas>
<h2>Upload a photo </h2>
<input type="file" onchange="previewFile()"><br>
<script type="text/javascript">
// setup the canvas
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// grab the photo and display in canvas
var photo = new Image();
function previewFile() {
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener("load", function () {
photo.src = reader.result;
canvas.height = photo.height;
canvas.width = photo.width;
ctx.drawImage(photo,0,0);
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
</script>
【问题讨论】:
标签:
javascript
canvas
safari
【解决方案1】:
您的问题肯定是由于您没有等待图像加载后才尝试在画布上绘制它。
即使源是dataURI,图片的加载也是异步的,所以你需要将你的绘图操作包裹在图片的onload事件中。
var photo = new Image();
photo.onload = function(){
canvas.height = photo.height;
...
}
...
reader.onload = function(){
// this will eventually trigger the image's onload event
photo.src = this.result;
}
但是,如果您只需要在画布上绘制图像,甚至不要使用 FileReader,实际上,readAsDataURL() 方法应该会在您的大脑中触发 I'm doing something wrong 错误。几乎所有您可以使用 Blob 的 dataURI 版本执行的操作,也可以使用 Blob 本身执行此操作,无需计算它也不会污染浏览器的内存。
例如,要显示图像供用户输入,您可以使用URL.createObjectURL(blob) 方法。
// setup the canvas
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// grab the photo and display in canvas
var photo = new Image();
// drawing operations should be in the mage's load event
photo.onload = function() {
// if you don't need to display this image elsewhere
URL.revokeObjectURL(this.src);
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
}
photo.onerror = function(e) {
console.warn('file format not recognised as a supported image');
}
file_input.onchange = function() {
// prefer 'this' over DOM selection
var file = this.files[0];
var url = URL.createObjectURL(file);
photo.src = url;
};
<canvas id="canvas" width="0" height="0"></canvas>
<h2>Upload a photo </h2>
<input type="file" id="file_input">
<br>
对于需要将此文件发送到其服务器的用户,请使用FormData 直接发送 Blob。如果您确实需要 dataURI 版本,请在服务器端进行转换。