The clipboard

Clipboard-related operations are relatively rare in daily front-end development. But for some specific application scenarios, it is necessary to use. For example: rich text editor development, CTRL + V upload pictures, automatic copy of alipay red envelope password (typical use of being badly played)

Clipboard operation path

Clipboard events

The most basic way to manipulate the clipboard is to listen for clipboard events. For compatibility reasons, clipboardData is generally accessed only in the clipboard event handler. Non-ie browser read data is available only during onPaste events. To use clipboard events to read and write data, the user must actively use a shortcut key or right-click menu. So the main application scenario of the listener board event is to intercept the data after the user triggers it.

document.execCommand

The document.execcommand () method is used to manipulate the contents of editable regions, such as the most commonly used ‘copy’ command to copy the contents of selected regions to the clipboard, With the window.getSelection() method, you can automatically select the content area and write the content to the clipboard. The clipboard.js library and automatic copy of red envelope password are mainly realized through this method.

There are some problems with this approach:

  • Chrome \ Safari does not support ‘paste’
  • Chrome cannot directly invoke the ‘copy’ command in the background
  • IE can directly invoke and click in the background to trigger the ‘copy’ command, but there will be a permission prompt

Asynchronous Clipboard API

As you can see from the above, manipulating the clipboard is limited and convoluted, and even more difficult, some features are impossible to implement. But there’s no denying that a big part of the confusion is security.

Just imagine, when you browse the web, click the page or button, and copy the Alipay password, what will happen? Uh, acceptable? What about ‘rm-rf /’? (I use Windows, what am I afraid of)

The Asynchronous Clipboard API and Clipboard Permissions API, which are additions to the Clipboard API, are designed to address this problem, dealing with all the twists and turns and security risks. As of now (2018.03), Chrome 66 has implemented some features, but it is expected to change in the future. This article will not cover the details. The characteristics are summarized as follows:

  • The call can be invoked only in HTTPS mode
  • The page can only be called if it is in the active TAB
  • Promise based for asynchronous operation and error handling
  • Implement programmatic paste (read) and copy (write)
  • Paste (read) and copy (write) Permissions have been added to the Permissions API, and the operation requires user authorization
  • The Clipboard Permissions API currently only works with the Asynchronous Clipboard API. According to the spec, it will be added to all Clipboard apis in the future

Process paste

For paste, currently widely supported only shortcut keys and right menu trigger, and IE supported programming mode use scenarios are few, not introduced here.

Plain text or formatted text

Interception of plain text

El.addEventListener('paste', event => {
    event.preventDefault();
    letClipboardData = event. The clipboardData | | window. The clipboardData, / / compatible plainText = clipboardData IE. GetData ('text'); // No format text //... Perform a series of operations on plainText document.execcommand ('insertText'.false, plainText); // Insert plain text document.execCommand('paste'.false, plainText); // IE compatible})Copy the code

If you need to further process the formatted text, you can use the following methods to convert it into a DOM structure and then operate it. (IE doesn’t have access to ‘text/ HTML ‘so you can’t do this.)

/* still in the above event handlers, */ is omitted belowlet plainHTML = clipboardData.getData('text/html'DomContainer = document.createElement('div'); domContainer.innerHTML = plainHTML; / /... Perform a series of operations on domContainer el.innerhtml = domContainer.innerhtml; // Insert el. appendChild(nodeOfDomContainer) as a whole with innerHTML; // Insert only one of the nodesCopy the code

The picture

If the DOM structure contains an image label, upload the image to the server and replace its SRC with the address returned by the server.

If the copied image is a single image (for example, copied from Word), you can use the following method to get the DataURL of the image and then upload it. (IE will automatically generate image labels with DataURL for pasting images, so the following method is not required)

    let items = clipboardData.items;
    for (let i = 0; i < items.length; i++) {
        let item = items[i];
        if (/image/.test(item.type)) {
            letReader = new FileReader(); reader.onload =function() {upload(reader.result) // upload image, false code} reader.readasdataurl (file); DataURL/Base64}}Copy the code

Handling copy

Shortcut keys and right menu trigger

The common application scenario is to intercept the copying operation and write the copied content into the clipboard after processing, for example, adding copyright information after copying a large section of text in Zhihu.

El.addEventListener('copy', event => {
    event.preventDefault();
    letclipboardData = event.clipboardData || window.clipboardData, text = window.getSelection().toString(); / /... Clipboarddata.setdata ('text/plain', text); // Write the processed text to the clipboarddata.setData ('text', text); // IE compatible})Copy the code

Programmatic replication

Although it is programmatic replication, it cannot be completely automatic replication, requiring the user to trigger the click event first. The clipboard.js library and automatic copy of the red envelope password (listening for click events on the document) are mainly implemented through this method.

Fixed content

Button.addEventListener('click', event => {
    let sometext = 'Red envelope code XXXXXX',
        hiddenInput = document.createElement('input');
    hiddenInput.value = sometext;
    hiddenInput.setAttribute('readonly'.' ');
    hiddenInput.style.position = 'absolute';
    hiddenInput.style.left = '-9999px';
    document.body.appendChild(hiddenInput);
    hiddenInput.select();
    hiddenInput.setSelectionRange(0, hiddenInput.value.length); // ios
    document.execCommand('copy');
    document.body.removeChild(hiddenInput);
})
Copy the code

Copies the text within an element

Button.addEventListener('click', event => {
    let someElement = document.getElementById('someelement'),
        selection = window.getSelection(),
        range = document.createRange();
    range.selectNodeContents(element);
    selection.removeAllRanges();
    selection.addRange(range);
    document.execCommand('copy');
})
Copy the code

As you can see, the clipboard operation is very strange at the moment, hopefully the new API will become a reality soon (dream)!

reference

[1] Clipboard API and events | w3c

[2] clipboard.js | Github

[3] using javascript | the nuggets rich text editor

[4] | asain nuggets rich text editor

[5] JavaScript duplicate content to clipboard | the Denver nuggets