• 善用 IIFE 以封装 BOM对象提供的方法


    1. 文件转 Base64

    在大规模使用 FileSystem接口之前,前端读取文件主要靠 input[type='file'] 元素。开发者通常会随手创建一个 FileReader 实例来读取文件,用完之后随即抛弃之,不得不说真是无情。实际上这个实例是可以复用起来的:

    /**
     * @method blob2Base64 - 将 blob 文件转为 Base64 URL
     * @returns {Promise<String>}
     * */
     const blob2Base64 = (() => {
        const fileReader = new FileReader();
        let resolver = null, errHandler = null;
        fileReader.onload = () => resolver(fileReader.result);
        fileReader.onerror = err => errHandler(err);
        
        return file => {
            fileReader.readAsDataURL(file);
            return new Promise((resolve, reject) => {
                resolver = resolve;
                errHandler = reject;
            })
        }
    })();

    这种代码最常用于读取用户选取的图片,使用的时候:

    const readFileFromInput = async event => {
        const { target: { files: [file] }} = event;
        const base64 = await blob2Base64(file);
        console.log('read data as base64:', base64);
    }
    document.querySelector('input[type="file"]').addEventListener('change', readFileFromInput);

    2. 从URL加载图片

    前端处理图片通常依赖于 canvas ,而 canvas 绘图上下文不支持直接从 URL 读取图片,所以我们需要创建一个图片对象,并在其加载完成后再绘制到 canvas 上,鉴于 canvas 会将图片数据复制一份,这个图片对象是可以复用的:

    /**
     * @const loadImageFromURL - 从 URL 加载图片
     * */
    const loadImageFromURL = (() => {
        const image = new Image();
        image.setAttribute('crossOrigin', 'Anonymous');
        let resolver = null, errHandler = null;
        image.onload = () => {
            resolver(image);
        };
        image.onerror = err => {
            errHandler(err);
        };
        return URL => {
            return new Promise((resolve, reject) => {
                resolver = resolve;
                errHandler = reject;
                image.src = URL;
            });
        }
    })();

    当然,如果是使用 Knova 这样的绘图库的话,每添加一张图片都需要创建新的 Image 对象,这段代码稍加修改就可以胜任了。

    3. 获取图片BitMap数据

    借助 canvas 我们可以将浏览器支持的所有格式的图片解码得到其位图数据,不过,这个需求并不常见,除非你想亲手实现一下二维码扫描功能。这里需要复用的,是一个 canvas 元素对象及其绘图上下文:

    /**
     * @method imageFileToImageData - 读取图片文件的为位图数据
     * @param {File} blob - 需要转换的文件对象
     * @return {Promise<ImageData>}
     */const imageFileToImageData = (() => {
        const canvas = document.createElement('canvas');
        canvas.setAttribute('crossOrigin', 'Anonymous');
        const context = canvas.getContext('2d');
        return async blob => {
            const image = await loadImageFromURL(await blob2Base64(blob));
            const { width, height } = image;
            canvas.setAttribute('width', width);
            canvas.setAttribute('height', height);
            context.drawImage(image, 0, 0, width, height);
            return context.getImageData(0, 0, width, height);
        };
    })();

    上面的两个方法在这里都已经用上了,可以看出简直是简洁、方便、清晰到家了!

    https://www.51220.cn 51220网站目录

    4. 文件下载

    文件下载的原理是借助一个 a[download] 元素触发点击事件,同样地,这个元素也是可以复用的:

    /**
     * 传入 URL 下载文件
     * */
    const downLoadPicByURL = (() => {
        const anchor = document.createElement('a');
        return (URL, filename = 'download') => {
            anchor.setAttribute('href', URL);
            anchor.setAttribute('download', filename);
            anchor.click();
        }
    })();

    当然,由于下载的过程没法监听更没法控制,这个方法不返回任何有效信息。

  • 相关阅读:
    生病了,难受啊
    2005年1月31号随笔一篇
    [转]永远的Beyond
    关于IE问题,请教和求救
    中国财富排行榜
    这两天简直倒霉透顶了
    Asp.net(C#)给图片加上水印效果
    我不爱的那个女人
    555,我的hotmail从2G变回2M的了
    怀念永远的战神
  • 原文地址:https://www.cnblogs.com/xiaonian8/p/15070815.html
Copyright © 2020-2023  润新知