dexteryao 发表于 2022-11-21 11:07:31

【SpreadJS v16.0 新特性预览】剪贴板事件增强(取消拷贝/剪切状态时)

本帖最后由 dexteryao 于 2022-11-30 14:03 编辑

由于浏览器安全性策略,使用Javascript代码操作系统剪切板有这诸多限制,在非浏览器复制粘贴事件中,无法直接获取和设置剪切板的内容。SpreadJS右键菜单(Content Menu)中的复制粘贴是普通的click行为,因此也是无法操作系统剪切板的,使用右键菜单只能做SpreadJS当前workbook中的复制粘贴(称之为内部粘贴)。结果就是当您从Excel中复制了数据,在SpreadJS中点击右键粘贴,无法将Excel中的内容复制过来(这种称之为外部粘贴),外部粘贴只能通过键盘c + v来实现。

好消息是部分浏览器开放 Clipboard 接口,在用户授权或者安装插件的情况下,普通事件中的Javascript代码可以通过Clipboard API获取和设置剪切板内容了。

SpreadJS V16 增强了剪切板事件,通过事件中提供的信息,可以实现更多的粘贴复制功能,比如选择性粘贴,结合Clipboard API 实现外部粘贴。

在ClipboardChanging, ClipboardPasting, ClipboardPasted事件中增加了action参数。
GC.Spread.Sheets.ClipboardActionType 是一个枚举项


export enum ClipboardActionType {
    /**
   * Indicates a copy action
   */
    copy = 1,
    /**
   * Indicates a cut action
   */
    cut = 2,
    /**
   * Indicates a reset action, the clipboard is reset at this point
   */
    reset = 3
}



当用户通过快捷键或右键菜单进行复制和前切时会触发action为copy和cut的事件,当用户按下esc或者编辑单元格、区域会清除复制数据并处罚action为reset的事件,reset标志着工作表中没有绿色虚线标记的复制区域提示。有了剪切板action在结合其他事件以及浏览器提供的Clipboard API,对于想对复制粘贴行为进行深度定制的用户来说就可以灵活操作了。

实践案例
   1. 实现内部选择性粘贴的精准控制


let clipboardHelper = {}
spread.bind(GC.Spread.Sheets.Events.ClipboardChanging, function (s, e) {
    if(e.action === GC.Spread.Sheets.ClipboardActionType.reset){
      clipboardHelper = {}
    }
    else{
      clipboardHelper.copiedSheet = e.sheet;
      clipboardHelper.copiedRanges = e.ranges;
      clipboardHelper.copiedObjects = e.objects;
      clipboardHelper.isCutting = e.isCutting;
    }
});




通过使用clipboardHelper可以实时记录内部剪切板变化情况,根据用户复制内容,以及选择区域精确的给出可粘贴内容

      2. 同步系统剪切板

结合Clipboard API ,将SpreadJS剪切板内容同步系统剪切板。

spread.bind(GC.Spread.Sheets.Events.ClipboardChanging, async function(s, e){
    console.log(s, e);
    const { state } = await navigator.permissions.query({
      name: "clipboard-write"
    });
    console.log(state)
    if(state === "granted"){
      let data = [];
      if(e.action === GC.Spread.Sheets.ClipboardActionType.reset){
            // 清楚剪切板内容
            data.push(new ClipboardItem({ "text/plain": new Blob([""], { type: "text/plain" }) }))
      }
      else if(e.copyData && e.copyData.text){
            // 设置文本到剪切板
            data.push(new ClipboardItem({ "text/plain": new Blob(, { type: "text/plain" }) }))
      }
      navigator.clipboard.write(data).then(function() {
            /* success */
            console.log("success");
      }, function() {
            /* failure */
            console.log("failure", arguments);
      });
    }
});

类似也可以在ClipboardPasting中navigator.clipboard.read读取剪切板信息,结合clipboardHelper 实现内外部的混合粘贴。

页: [1]
查看完整版本: 【SpreadJS v16.0 新特性预览】剪贴板事件增强(取消拷贝/剪切状态时)