2014 年 1 月 31 日星期五

HTML 5 剪贴板和文件 API

我收到的一个最常见的问题是关于 TableTools 是否有可能移除 Flash 依赖性。直到最近,答案一直都是 no,但现在隧道尽头可能有了光亮,因为 W3C 提出了新的 API。

TableTools 使用 Flash 的目的有两个

  • 复制到剪贴板
  • 将数据保存到本地文件

当前在各个浏览器中都没有实现任何 API,能够为我们提供 TableTools 中所需的功能,而无需使用 Flash 就能提供这两个基本功能。但是,W3C 正在为这些任务的执行开发 API,并且希望不久之后这些任务会被逐步添加到浏览器中。

在继续之前警告您一句 - 这篇文章是根据 编辑草案工作草案 状态规范文件中所提供的信息编写的,如 W3C 所定义。未来规范可能会发生变更。

剪贴板 API

我们感兴趣的第一个 API 是 剪贴板 API。当前的规范主要关注事件:copycutpaste,以及通过明确定义的 API(ClipboardEvent 对象)来收听这些事件的能力。

最新的 编辑草案 添加了创建这些事件的能力,称为 合成事件,感谢 ZeroClipboard 项目 的 James Greene 提交了一个 bug,TableTools 目前使用了这个项目。

有了这些合成事件,我们便能够创建一个新的 ClipboardEvent 对象,并像任何其他 DOM 事件一样触发它。这些剪贴板事件被称为 半受信任 事件,因此您的浏览器会询问您是否要允许该域使用剪贴板操作,这种方式与当前页面可能会询问您是否允许它们使用地理位置 API 获取您位置的方式非常相似。

就提议的 API 来说,示例如下:TableTools 能够使用以下内容将表信息复制为 CSV 格式并复制到剪贴板

$(button).on( 'click', function (e) {
    var data = table
        .data()
        .map( function (row) {
            return row.join(',');
        } )
        .join( '\n' );

    var clip = new ClipboardEvent( 'copy' );
    clip.clipboardData.setData( 'text/plain', data );
    clip.preventDefault();

    e.target.dispatchEvent( clip );
} );

这当然是一个简化的案例,因为它没有提供 TableTools 提供的众多配置选项,但从中可以看出我们利用这个出色新 API 的方式会多么简单。

文件 API

按需在 Javascript 中创建文件的能力,是我们感兴趣的第二个新 API TableTools 的基石 - 文件写入器 API

已经有一些方法可以使用 HTML 创建和保存文件,包括使用data://伪协议,但这些方法有着诸如在旧浏览器中无法工作、不能总是对文件进行命名以及没有 Flash FileReference API 简洁易用的语法的局限。但是,新的文件编写器 API 将在 JavaScript 中为我们提供上述所有功能。

在撰写本文时,文件编写器 API 定义了 saveAs全局函数(我认为这很可能在规范最终确定之前发生改变,因为很可能会产生名称冲突),它仅获取 Blob 和文件名称,以将 blob 中的数据另存为该文件名称。

回到我们再次通过表保存 CSV 数据的示例,现在,保存到本地文件的代码如下

$(button).on( 'click', function (e) {
    var data = table
        .data()
        .map( function (row) {
            return row.join(',');
        } )
        .join( '\n' );

    saveAs(
        new Blob( [data], {type : 'text/csv'},
        'My file.csv'
    );
} );

虽然仍处于工作草案阶段,但文件编写器 API 比剪贴板 API 更加成熟,且 Microsoft 已经在 IE10+ 中实现了此 API。其他浏览器尚未推出此功能,但诸如 Eli Grey 的 FileSaver 等垫片层已在许多浏览器中提供了此功能。

结论

长期以来,网民开发的世界都不再使用 Flash,但 Web 开发人员却不得不借助 Flash 来实现 TableTools 中像复制到剪贴板和保存到文件这样的简单任务,这让人感到非常沮丧。但随着这两个规范在 W3C 中不断推进以及浏览器开发人员有望在不久的将来对它们进行实现,TableTools 不再需要 Flash 的日子或许并不遥远。