You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Electron中混合使用自定义撤销逻辑与webContents.undo()方法

实现方案

要判断当前focusedWin.webContents是否可以处理撤销操作,核心是查询当前页面上下文的撤销命令可用状态,Electron主进程可以通过向渲染进程注入JS执行的方式拿到该状态,完整实现如下:

完整菜单项代码

{
  label: 'Undo',
  accelerator: 'CmdOrCtrl+Z',
  click: async function(menuItem, focusedWin) {
    // 向当前聚焦窗口注入JS查询撤销命令是否可用
    const canUndo = await focusedWin.webContents.executeJavaScript(`
      document.queryCommandEnabled('undo')
    `)
    if (canUndo) {
      focusedWin.webContents.undo()
    } else {
      // 此处运行你的自定义撤销逻辑
    }
  }
}

方案说明

document.queryCommandEnabled 虽然被标准标记为废弃,但目前Electron内嵌的所有Chromium版本都完全支持该API,判断精度最高,可以直接识别可编辑元素中是否存在可撤销的历史栈。

兼容替代方案

如果你担心未来API被移除,可以改用判断当前焦点是否位于可编辑元素的方案,兼容性更强:

{
  label: 'Undo',
  accelerator: 'CmdOrCtrl+Z',
  click: async function(menuItem, focusedWin) {
    const isFocusedEditable = await focusedWin.webContents.executeJavaScript(`
      const activeEl = document.activeElement;
      if (!activeEl) false;
      activeEl.tagName === 'TEXTAREA' 
      || (activeEl.tagName === 'INPUT' && ['text','password','search','number','email','url'].includes(activeEl.type))
      || activeEl.isContentEditable
    `)
    if (isFocusedEditable) {
      focusedWin.webContents.undo()
    } else {
      // 此处运行你的自定义撤销逻辑
    }
  }
}

该方案的缺点是无法判断可编辑元素内是否真的有可撤销的历史,但即使没有可撤销内容,调用webContents.undo()也不会产生任何报错或副作用,完全可以满足绝大多数场景的需求。

Redo逻辑适配

重做的实现逻辑完全一致,只需要将代码中所有undo替换为redo即可。

内容的提问来源于stack exchange,提问作者YannZeRookie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 08:06:07