Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
540 views
in Technique[技术] by (71.8m points)

javascript - JavaScript在粘贴事件中获取剪贴板数据(跨浏览器)(JavaScript get clipboard data on paste event (Cross browser))

How can a web application detect a paste event and retrieve the data to be pasted?

(Web应用程序如何检测粘贴事件并检索要粘贴的数据?)

I would like to remove HTML content before the text is pasted into a rich text editor.

(在将文本粘贴到RTF编辑器中之前,我想删除HTML内容。)

Cleaning the text after being pasted afterwards works, but the problem is that all previous formatting is lost.

(之后粘贴后清除文本是可行的,但是问题是所有以前的格式都丢失了。)

For example, I can write a sentence in the editor and make it bold, but when I paste new text, all formatting is lost.

(例如,我可以在编辑器中写一个句子并将其设置为粗体,但是当我粘贴新文本时,所有格式都将丢失。)

I want to clean just the text that is pasted, and leave any previous formatting untouched.

(我只想清除粘贴的文本,并保留所有以前的格式。)

Ideally, the solution should work across all modern browsers (eg, MSIE, Gecko, Chrome, and Safari).

(理想情况下,该解决方案应可在所有现代浏览器(例如MSIE,Gecko,Chrome和Safari)上运行。)

Note that MSIE has clipboardData.getData() , but I could not find similar functionality for other browsers.

(请注意,MSIE具有clipboardData.getData() ,但是我找不到其他浏览器的类似功能。)

  ask by Alex translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Solution #1 (Plain Text only and requires Firefox 22+)(解决方案1(仅纯文本,需要Firefox 22+))

Works for IE6+, FF 22+, Chrome, Safari, Edge (Only tested in IE9+, but should work for lower versions)

(适用于IE6 +,FF 22 +,Chrome,Safari,Edge(仅在IE9 +中经过测试,但应在较低版本中使用))

If you need support for pasting HTML or Firefox <= 22, see Solution #2.

(如果需要粘贴<= 22的HTML或Firefox的支持,请参阅解决方案#2。)

HTML(的HTML)

<div id='editableDiv' contenteditable='true'>Paste</div>

JavaScript(的JavaScript)

function handlePaste (e) {
    var clipboardData, pastedData;

    // Stop data actually being pasted into div
    e.stopPropagation();
    e.preventDefault();

    // Get pasted data via clipboard API
    clipboardData = e.clipboardData || window.clipboardData;
    pastedData = clipboardData.getData('Text');

    // Do whatever with pasteddata
    alert(pastedData);
}

document.getElementById('editableDiv').addEventListener('paste', handlePaste);

JSFiddle: https://jsfiddle.net/swL8ftLs/12/

(JSFiddle: https ://jsfiddle.net/swL8ftLs/12/)

Note that this solution uses the parameter 'Text' for the getData function, which is non-standard.

(请注意,此解决方案为getData函数使用参数'Text',这是非标准的。)

However, it works in all browsers at the time of writing.

(但是,在撰写本文时,它可在所有浏览器中使用。)


Solution #2 (HTML and works for Firefox <= 22)(解决方案#2(HTML且适用于Firefox <= 22))

Tested in IE6+, FF 3.5+, Chrome, Safari, Edge

(在IE6 +,FF 3.5 +,Chrome,Safari,Edge中测试)

HTML(的HTML)

<div id='div' contenteditable='true'>Paste</div>

JavaScript(的JavaScript)

var editableDiv = document.getElementById('editableDiv');

function handlepaste (e) {
    var types, pastedData, savedContent;

    // Browsers that support the 'text/html' type in the Clipboard API (Chrome, Firefox 22+)
    if (e && e.clipboardData && e.clipboardData.types && e.clipboardData.getData) {

        // Check for 'text/html' in types list. See abligh's answer below for deatils on
        // why the DOMStringList bit is needed. We cannot fall back to 'text/plain' as
        // Safari/Edge don't advertise HTML data even if it is available
        types = e.clipboardData.types;
        if (((types instanceof DOMStringList) && types.contains("text/html")) || (types.indexOf && types.indexOf('text/html') !== -1)) {

            // Extract data and pass it to callback
            pastedData = e.clipboardData.getData('text/html');
            processPaste(editableDiv, pastedData);

            // Stop the data from actually being pasted
            e.stopPropagation();
            e.preventDefault();
            return false;
        }
    }

    // Everything else: Move existing element contents to a DocumentFragment for safekeeping
    savedContent = document.createDocumentFragment();
    while(editableDiv.childNodes.length > 0) {
        savedContent.appendChild(editableDiv.childNodes[0]);
    }

    // Then wait for browser to paste content into it and cleanup
    waitForPastedData(editableDiv, savedContent);
    return true;
}

function waitForPastedData (elem, savedContent) {

    // If data has been processes by browser, process it
    if (elem.childNodes && elem.childNodes.length > 0) {

        // Retrieve pasted content via innerHTML
        // (Alternatively loop through elem.childNodes or elem.getElementsByTagName here)
        var pastedData = elem.innerHTML;

        // Restore saved content
        elem.innerHTML = "";
        elem.appendChild(savedContent);

        // Call callback
        processPaste(elem, pastedData);
    }

    // Else wait 20ms and try again
    else {
        setTimeout(function () {
            waitForPastedData(elem, savedContent)
        }, 20);
    }
}

function processPaste (elem, pastedData) {
    // Do whatever with gathered data;
    alert(pastedData);
    elem.focus();
}

// Modern browsers. Note: 3rd argument is required for Firefox <= 6
if (editableDiv.addEventListener) {
    editableDiv.addEventListener('paste', handlepaste, false);
}
// IE <= 8
else {
    editableDiv.attachEvent('onpaste', handlepaste);
}

JSFiddle: https://jsfiddle.net/nicoburns/wrqmuabo/23/

(JSFiddle: https ://jsfiddle.net/nicoburns/wrqmuabo/23/)

Explanation(说明)

The onpaste event of the div has the handlePaste function attached to it and passed a single argument: the event object for the paste event.

(divonpaste事件具有附加的handlePaste函数,并传递了一个参数:粘贴事件的event对象。)

Of particular interest to us is the clipboardData property of this event which enables clipboard access in non-ie browsers.

(我们特别感兴趣的是此事件的clipboardData属性,该属性允许在非浏览器中访问剪贴板。)

In IE the equivalent is window.clipboardData , although this has a slightly different API.

(在IE中,等效的是window.clipboardData ,尽管它的API略有不同。)

See resources section below.

(请参阅下面的资源部分。)


The handlepaste function:

(handlepaste功能:)

This function has two branches.

(此功能有两个分支。)

The first checks for the existence of event.clipboardData and checks whether it's types property contains 'text/html' ( types may be either a DOMStringList which is checked using the contains method, or a string which is checked using the indexOf method).

(第一个检查event.clipboardData是否存在,并检查它的types属性是否包含“ text / html”( types可以是使用contains方法检查的DOMStringList ,或者是使用indexOf方法检查的字符串)。)

If all of these conditions are fulfilled, then we proceed as in solution #1, except with 'text/html' instead of 'text/plain'.

(如果所有这些条件都满足,那么我们按照解决方案#1进行,除了使用'text / html'而不是'text / plain'。)

This currently works in Chrome and Firefox 22+.

(目前,该功能适用??于Chrome和Firefox 22+。)

If this method is not supported (all other browsers), then we

(如果不支持此方法(所有其他浏览器),那么我们)

  1. Save the element's contents to a DocumentFragment

    (将元素的内容保存到DocumentFragment)

  2. Empty the element

    (清空元素)

  3. Call the waitForPastedData function

    (调用waitForPastedData函数)


The waitforpastedata function:

(waitforpastedata函数:)

This function first polls for the pasted data (once per 20ms), which is necessary because it doesn't appear straight away.

(此功能首先轮询粘贴的数据(每20毫秒一次),这是必需的,因为它不会立即出现。)

When the data has appeared it:

(数据出现后:)

  1. Saves the innerHTML of the editable div (which is now the pasted data) to a variable

    (将可编辑div的innerHTML(现在是粘贴的数据)保存到变量中)

  2. Restores the content saved in the DocumentFragment

    (恢复保存在DocumentFragment中的内容)

  3. Calls the 'processPaste' function with the retrieved data

    (使用检索到的数据调用“ processPaste”函数)


The processpaste function:

(processpaste功能:)

Does arbitrary things with the pasted data.

(对粘贴的数据进行任意处理。)

In this case we just alert the data, you can do whatever you like.

(在这种情况下,我们只是提醒数据,您可以做任何您想做的事。)

You will probably want to run the pasted data through some kind of data sanitising process.

(您可能需要通过某种数据清理过程来运行粘贴的数据。)


Saving and restoring the cursor position

(保存和还原光标位置)

In a real sitution you would probably want to save the selection before, and restore it afterwards ( Set cursor position on contentEditable <div> ).

(在实际情况中,您可能希望先保存选择,然后再恢复选择( 将光标位置设置在contentEditable <div>上 )。)

You could then insert the pasted data at the position the cursor was in when the user initiated the paste action.

(然后,您可以在用户启动粘贴操作时将粘贴的数据插入光标所在的位置。)

Resources:(资源:)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...