【问题标题】: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 版本,请在服务器端进行转换。

    【讨论】:

    • 非常感谢!这解决了问题,你教会了我一两件事!
    猜你喜欢
    • 2018-05-19
    • 2011-02-22
    • 1970-01-01
    • 1970-01-01
    • 2021-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    相关资源
    最近更新 更多