[js] 快速输入时间

演示

输入 sjsj (首尾空格或尾空格,通过编辑代码切换)替换为 HH:mm

方便使用英文输入法时快速输入时间。

PixPin20250909162331.webp

使用方式

如何使用代码片段? - 思源笔记社区平台

代码

(() => {
  /* ================== 配置 ================== */
  const DEBUG = false;
  
  /**
   * 是否忽略头部的空格
   * - false: 匹配完整的 " sj " (空格, s, j, 空格)
   * - true:  只匹配 "sj " (s, j, 空格)
   */
  const IGNORE_HEAD_SPACE = true;

  // 根据开关动态确定目标序列
  const SEQ = IGNORE_HEAD_SPACE ? ['s', 'j', ' '] : [' ', 's', 'j', ' '];

  /* ================== 日志 ================== */
  const log = (...a) => { if (DEBUG) console.log('[TimeShort]', ...a); };
  log(`脚本已启动。当前匹配序列: "${SEQ.join('')}"`);

  /* ================== 缓冲 ================== */
  const BUF = [];

  /* ================== 工具 ================== */
  const fmtTime = () => {
    const d = new Date();
    return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
  };

  const isInputLike = el =>
    el && (
      el.tagName === 'INPUT' ||
      el.tagName === 'TEXTAREA' ||
      el.isContentEditable
    );

  /* =============== 替换主逻辑 (模拟键盘操作) =============== */
  const doReplace = (el) => {
    if (!isInputLike(el)) { log('忽略非输入元素', el); return; }
  
    el.focus();

    // 最后一个触发字符 (空格) 被 preventDefault() 拦截了,未输入
    // 因此需要删除的字符数是序列长度减一
    const deleteCount = SEQ.length - 1;
  
    log(`模拟 ${deleteCount} 次退格...`);
    for (let i = 0; i < deleteCount; i++) {
      document.execCommand('delete', false, null);
    }

    const timeStr = fmtTime();
    log(`插入时间: "${timeStr}"`);
    document.execCommand('insertText', false, timeStr);

    log(`已替换 → "${timeStr}"`);
  };

  /* =============== 键盘监听 (快速失败逻辑) =============== */
  document.addEventListener('keydown', (e) => {
    // 忽略带有修饰键的按键,以避免与快捷键冲突
    if (e.metaKey || e.ctrlKey || e.altKey) {
      BUF.length = 0; // 中断序列
      return;
    }

    const el = e.target;
    const key = e.key;

    // 检查新按键是否能延续当前序列
    // SEQ[BUF.length] 是期望的下一个字符
    if (key === SEQ[BUF.length]) {
      BUF.push(key);
      log('序列匹配中:', `"${BUF.join('')}"`);
    } else {
      // 序列中断,快速失败
      // 检查当前按键是否是新序列的开始
      if (key === SEQ[0]) {
        // 是,则以当前按键开始一个新的序列
        BUF.length = 1;
        BUF[0] = key;
        log('序列中断,但当前键是新序列的开始:', `"${BUF.join('')}"`);
      } else {
        // 不是,则彻底清空缓冲
        if (BUF.length > 0) {
            log('序列中断,缓冲已清空。');
            BUF.length = 0;
        }
      }
    }

    // 判断序列是否完整匹配
    if (BUF.length === SEQ.length) {
      log('序列匹配成功!');
  
      // 阻止默认行为!防止最后一个字符(空格)被实际输入
      e.preventDefault();
      e.stopPropagation();

      doReplace(el);
  
      // 清空缓冲,为下一次做准备
      BUF.length = 0;
    }
  }, true);   // 在捕获阶段监听
})();
  • 代码片段

    代码片段分为 CSS 与 JS 两种代码,添加在 [设置 - 外观 - 代码片段] 中,这些代码会在思源笔记加载时自动执行,用于改善笔记的样式或功能。

    用户在该标签下分享代码片段时需在帖子标题前添加 [css] [js] 用于区分代码片段类型。

    285 引用 • 1986 回帖
  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    28446 引用 • 119783 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...