1
头图

Preface

Because to complete the clipboard history function, after consulting the electron clipboard document. No hook event for clipboard change was found, so I decided to implement one myself.

electron has an clipboard content. You can use this API to encapsulate the monitoring timer method. The specific logic is as follows:

Use the timer to continuously judge whether the content is the same, if not the same. Execute clipboard change callback

Write a clipboard observer class, and pass in the message/picture change callback to listen to when instantiating. Since frequent access to the clipboard content may bring a performance burden, it is also necessary to support the incoming custom listening interval.

The returned instance should support methods to pause and continue monitoring.

Write the clipboard observer class

First define the interface of the constructor parameters

import { clipboard, NativeImage } from 'electron';

interface Options {
  //  定时器获取内容判断的间隔
  duration?: number;
  //  文本变化回调
  textChange?: (text: string, beforeText: string) => void;
  //  图片变化回调
  imageChange?: (image: NativeImage, beforeImage: NativeImage) => void;
}

Then define the class, write the logic and exposed api in the constructor to process the parameters

class ClipboardObserver {
  //  定时器
  timer: NodeJS.Timeout;
  //  变化前的文本(用于对比新获取的剪贴板文本)
  beforeText: string;
  //  变化去的图片(用于对比新获取的剪贴板图片)
  beforeImage: NativeImage;

  duration = 500;
  textChange: (text: string, beforeText: string) => void;
  imageChange: (image: NativeImage, beforeImage: NativeImage) => void;

  constructor(options: Options) {
    //  获取传入配置并保存到属性中
    const { duration, textChange, imageChange } = options;

    this.duration = duration;
    this.textChange = textChange;
    this.imageChange = imageChange;

    //  判断传入回调,默认开始执行定时器
    if (this.textChange || this.imageChange) {
      this.start();
    }
  }

  /**
   * 开始
   */
  start(): void {
    //  记录剪贴板目前的内容
    this.setClipboardDefaultValue();
    //  设置定时器
    this.setTimer();
  }

  /**
   * 暂停
   */
  stop(): void {
    //  清除定时器
    this.setTimer();
  }
}

clearTimer is responsible for calling clearInterval to clear the timer, and setClipboardDefaultValue is responsible for setting the record of the last change in the instance.

class ClipboardObserver {
  ...

  /**
   * 清除定时器
   */
  clearTimer(): void {
    clearInterval(this.timer);
  }

  /**
   * 设置剪贴板默认内容
   */
  setClipboardDefaultValue(): void {
    if (this.textChange) {
      //  electron剪贴板读取文本方法
      this.beforeText = clipboard.readText();
    }
    if (this.imageChange) {
      //  electron剪贴板读取图片方法
      this.beforeImage = clipboard.readImage();
    }
  }
}

setTimer is responsible for comparing the core logic, setting the timer, and judging whether the content has changed in each round of timer callback. If the content changes, execute the content change callback.

class ClipboardObserver {
  ...

  /**
   * 设置定时器
   */
  setTimer(): void {
    //  设置定时器
    this.timer = setInterval(() => {
      if (this.textChange) {
        const text = clipboard.readText();
        //  判断内容是否与上次读取的内容不同
        if (this.isDiffText(this.beforeText, text)) {
          //  执行变化回调
          this.textChange(text, this.beforeText);
          //  记录此次内容
          this.beforeText = text;
        }
      }

      if (this.imageChange) {
        const image = clipboard.readImage();
        //  判断内容是否与上次读取的内容不同
        if (this.isDiffImage(this.beforeImage, image)) {
          //  执行变化回调
          this.imageChange(image, this.beforeImage);
          //  记录此次内容
          this.beforeImage = image;
        }
      }
    }, this.duration);
  }

  /**
   * 判断内容是否不一致
   * @param beforeText
   * @param afterText
   * @returns
   */
  isDiffText(beforeText: string, afterText: string): boolean {
    return afterText && beforeText !== afterText;
  }

  /**
   * 判断图片是否不一致
   * @param beforeImage
   * @param afterImage
   * @returns
   */
  isDiffImage(beforeImage: NativeImage, afterImage: NativeImage): boolean {
    return afterImage && !afterImage.isEmpty() && beforeImage.toDataURL() !== afterImage.toDataURL();
  }
}

Finish work

At this point, the logic of the clipboard observer class has been completed. We can eat like this in the code

const clipboardObserver = new ClipboardObserver({
  textChange: (text: string, beforeText: string) => {
    //  处理文本变化的逻辑
  },
  imageChange: (image: Electron.NativeImage, beforeText: Electron.NativeImage) => {
    //  处理图片变化的逻辑
  }
});

//  也可以暂停
clipboardObserver.stop();

//  也可以再开始
clipboardObserver.start();

The project has been open sourced to electron-clipboard-observer . You can copy the code to the project for use

You can also install the dependency electron-clipboard-observer in the project and use it directly in the project after installation.

npm install electron-clipboard-observer

或者

yarn add electron-clipboard-observer

use

import ClipboardObserver from "electron-clipboard-observer"

const clipboardObserver = new ClipboardObserver({
    textChange() {},
    imageChange() {}
})

project address

Code warehouse

npm


onaug6th
69 声望8 粉丝

github: onaug6th