最简单、最简洁的 FileReader API 实现来抓取本地图像并显示它?

Simplest, leanest implementation of FileReader API to grab a local image and display it?

我正在尝试使用 FileReader API 来抓取本地图像,然后将其显示在网页上。

我参考了 MDN 的页面集合(从这里开始:https://developer.mozilla.org/en-US/docs/Web/API/FileReader),也参考了 Treehouse,但最初似乎有很多复杂的事情需要处理,我希望保持我的功能简洁,尽可能省去多余的杂物。

基本上我想部署尽可能简单的脚本,不要让它变得太简单。

这是我整理的 getLocalImage() 函数:

var body = document.getElementsByTagName('body')[0];
var fileInput = document.querySelector('input[type=file]');

function getLocalImage() {
    var image = document.createElement('img');

    var reader = new FileReader();

    var imageFile = fileInput.files[0];
    reader.readAsDataURL(imageFile);

    reader.onload = function(e) {
        image.src = reader.result;
    }

    body.appendChild(image);
}

fileInput.addEventListener('change',getLocalImage,false);
<input type="file" />

我的问题很简单:

  1. 这个脚本能再简单点吗? (我持怀疑态度,但我很想知道)。
  2. 更中肯一点,这个脚本简单吗?我是否遗漏了任何最佳实践? (例如,我是否也应该获取本地图像的尺寸,然后在网页上进行设置?)
  • 您可以为文件选择器定义accept属性,这样就可以只选择图片:

    <input type="file" accept="image/*" />

  • change 回调中,您应该检查用户是否选择了文件,或者使用取消按钮清除了选择。

  • 您可以使用 URL.createObjectURL 从所选文件创建图像 url。

这里有两个选项,一旦您的示例被重构,就可以使用一些性能测量来查看 FileReader 和 ObjectUrl 的比较。

function localImageSelected(event) {
    var files = event.target.files;
    if (files.length === 0) {
        return;
    } 
    var file = files[0];

    getImageSrcFromFile(file, function(src){
        var image = document.createElement('img');
        var now = performance.now();
        image.src = src;
        image.onload = function(){
            console.log('Image loaded in:', performance.now() - now);
        };
        document.body.appendChild(image);
    });     
}

function getImageSrcFromFile (file, cb) {
    var now = performance.now();
    var reader = new FileReader();
    reader.onload = function(e) {
        console.log('The url created in:', performance.now() - now);
        cb(reader.result);
    };
    reader.readAsDataURL(file);
}

document
    .querySelector('input[type=file]')
    .addEventListener('change', localImageSelected, false);

并使用 ObjectURL:

function localImageSelected(event) {
    var files = event.target.files;
    if (files.length === 0) {
        return;
    } 
    var file = files[0];

    var image = document.createElement('img');
    var url = getImageSrcFromFile(file);
    var now = performance.now();
    image.src = url;
    image.onload = function(){
        console.log('Image loaded in:', performance.now() - now);

        //I do it here, but note that the url is not more usable. 
        // Or you can remove this line, then extra KBs are in memory until the page reload, 
        // usually it is not critical
        URL.revokeObjectURL(url);
    };
    document.body.appendChild(image);
}

function getImageSrcFromFile (file) {
    var now = performance.now();
    var url = URL.createObjectURL(file);
    console.log('The url created in:', performance.now() - now);
    return url;
}

document
    .querySelector('input[type=file]')
    .addEventListener('change', localImageSelected, false);

我更喜欢 ObjectURL,因为它快 2 倍并且消耗更少的内存,但您必须注意手动撤销 url,因为加载的图像会保留在内存中,直到页面重新加载。 Datareader 的 base64 字符串在不再需要时由垃圾收集器清理。

您可以在此处找到更好的比较