代码之家  ›  专栏  ›  技术社区  ›  Alex

javascript获取粘贴事件的剪贴板数据(跨浏览器)

  •  265
  • Alex  · 技术社区  · 15 年前

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

    我希望在将文本粘贴到富文本编辑器之前删除HTML内容。

    在粘贴后清除文本是有效的,但问题是所有以前的格式都丢失了。例如,我可以在编辑器中编写一个句子并将其变为粗体,但是当我粘贴新文本时,所有格式都将丢失。我只想清除粘贴的文本,并保留任何以前的格式。

    理想情况下,该解决方案应适用于所有现代浏览器(如MSIE、Gecko、Chrome和Safari)。

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

    20 回复  |  直到 6 年前
        1
  •  134
  •   Community CDub    8 年前

    在写下这个答案后情况发生了变化:既然火狐在版本22中增加了支持,所有主要的浏览器现在都支持在粘贴事件中访问剪贴板数据。见 Nico Burns's answer 举个例子。

    在过去,这通常不可能以跨浏览器的方式实现。理想情况是能够通过 paste 事件, which is possible in recent browsers 但在一些老版本的浏览器(尤其是Firefox<22)中没有。

    当你需要支持老版本的浏览器时,你所能做的就是参与其中,并且有一点黑客行为可以在firefox 2+、ie 5.5+和webkit浏览器(如safari或chrome)中使用。Tinymce和Keckeditor的最新版本都使用此技术:

    1. 使用按键事件处理程序检测ctrl-v/shift-ins事件
    2. 在这个处理程序中,保存当前的用户选择,在屏幕外添加一个textArea元素(比如在左边-1000px),然后 designMode 关闭和呼叫 focus() 在文本区域上,从而移动插入符号并有效地重定向粘贴
    3. 在事件处理程序中设置一个非常短的计时器(例如1毫秒),以调用另一个存储textArea值的函数,从文档中删除textArea,然后旋转 设计模式 重新打开,恢复用户选择并粘贴文本。

    请注意,这只适用于键盘粘贴事件,而不是从上下文或编辑菜单粘贴。当粘贴事件触发时,将插入符号重定向到文本区域(至少在某些浏览器中)为时已晚。

    如果您不太可能需要支持firefox 2,请注意,您需要将文本区域放在父文档中,而不是将wysiwyg编辑器iframe的文档放在该浏览器中。

        2
  •  276
  •   Community CDub    8 年前

    解决方案1(纯文本,需要Firefox 22+)

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

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

    HTML

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

    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/

    请注意,此解决方案使用参数“text”作为 getData 功能,这是非标准的。但是,它在编写时可以在所有浏览器中工作。


    解决方案2(HTML,适用于Firefox<=22)

    在IE6+、FF 3.5+、Chrome、Safari、Edge中测试

    HTML

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

    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/

    解释

    这个 onpaste 事件 div handlePaste 函数附加到它并传递一个参数: event 粘贴事件的对象。我们特别感兴趣的是 clipboardData 此事件的属性,用于在非IE浏览器中访问剪贴板。在IE中,等价物是 window.clipboardData 尽管这有一个稍微不同的API。

    请参阅下面的参考资料部分。


    这个 handlepaste 功能:

    此函数有两个分支。

    第一个检查是否存在 event.clipboardData 检查它是否 types 属性包含“text/html”( 类型 可能是 DOMStringList 使用 contains 方法,或使用 indexOf 方法)。如果所有这些条件都满足,那么我们将按照解决方案1中的步骤进行,除了“text/html”而不是“text/plain”。这目前在Chrome和Firefox 22+中有效。

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

    1. 将元素的内容保存到 DocumentFragment
    2. 清空元素
    3. 打电话给 waitForPastedData 功能

    这个 waitforpastedata 功能:

    此函数首先对粘贴的数据进行轮询(每20毫秒一次),这是必需的,因为它不会直接显示出来。当数据出现时:

    1. 将可编辑DIV(现在是粘贴的数据)的innerhtml保存到变量
    2. 还原文档片段中保存的内容
    3. 使用检索到的数据调用“processPaste”函数

    这个 processpaste 功能:

    使用粘贴的数据执行任意操作。在这种情况下,我们只是提醒数据,您可以做任何您喜欢的事情。您可能希望通过某种数据消毒过程来运行粘贴的数据。


    保存和恢复光标位置

    在实际情况下,您可能希望先保存选择,然后再恢复选择。( Set cursor position on contentEditable <div> )然后可以在用户启动粘贴操作时光标所在的位置插入粘贴的数据。

    资源:

    感谢蒂姆建议使用documentfragment,并且能够捕获由于使用domstringlist而导致的firefox错误,而不是clipboarddata类型的字符串。

        3
  •  116
  •   l2aelba    6 年前

    简单版本:

    document.querySelector('[contenteditable]').addEventListener('paste', (e) => {
        e.preventDefault();
        const text = (e.originalEvent || e).clipboardData.getData('text/plain');
        window.document.execCommand('insertText', false, text);
    });
    

    使用 clipboardData

    演示: http://jsbin.com/nozifexasu/edit?js,output

    Edge、Firefox、Chrome、Safari、Opera测试。


    注: 记住检查输入/输出 服务器端 同样(类似) PHP strip-tags )

        4
  •  24
  •   vsync    7 年前

    Live Demo

    在Chrome/FF/IE11上测试

    这些浏览器添加了一个chrome/ie烦恼 <div> 每个新行的元素。有关于这个的帖子 here 它可以通过设置 可满足的 元素将是 display:inline-block

    选择一些突出显示的HTML并粘贴到此处:

    function onPaste(e){
      var content;
      e.preventDefault();
    
      if( e.clipboardData ){
        content = e.clipboardData.getData('text/plain');
        document.execCommand('insertText', false, content);
        return false;
      }
      else if( window.clipboardData ){
        content = window.clipboardData.getData('Text');
        if (window.getSelection)
          window.getSelection().getRangeAt(0).insertNode( document.createTextNode(content) );
      }
    }
    
    
    /////// EVENT BINDING /////////
    document.querySelector('[contenteditable]').addEventListener('paste', onPaste);
    [contenteditable]{ 
      /* chroem bug: https://stackoverflow.com/a/24689420/104380 */
      display:inline-block;
      width: calc(100% - 40px);
      min-height:120px; 
      margin:10px;
      padding:10px;
      border:1px dashed green;
    }
    
    /* 
     mark HTML inside the "contenteditable"  
     (Shouldn't be any OFC!)'
    */
    [contenteditable] *{
      background-color:red;
    }
    <div contenteditable></div>
        5
  •  15
  •   JanM    13 年前

    我在这里用屏幕外的文本区为TimDowns的提案写了一些概念证明。代码如下:

    <html>
    <head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> 
    <script language="JavaScript">
     $(document).ready(function()
    {
    
    var ctrlDown = false;
    var ctrlKey = 17, vKey = 86, cKey = 67;
    
    $(document).keydown(function(e)
    {
        if (e.keyCode == ctrlKey) ctrlDown = true;
    }).keyup(function(e)
    {
        if (e.keyCode == ctrlKey) ctrlDown = false;
    });
    
    $(".capture-paste").keydown(function(e)
    {
        if (ctrlDown && (e.keyCode == vKey || e.keyCode == cKey)){
            $("#area").css("display","block");
            $("#area").focus();         
        }
    });
    
    $(".capture-paste").keyup(function(e)
    {
        if (ctrlDown && (e.keyCode == vKey || e.keyCode == cKey)){                      
            $("#area").blur();
            //do your sanitation check or whatever stuff here
            $("#paste-output").text($("#area").val());
            $("#area").val("");
            $("#area").css("display","none");
        }
    });
    
    });
    </script>
    
    </head>
    <body class="capture-paste">
    
    <div id="paste-output"></div>
    
    
        <div>
        <textarea id="area" style="display: none; position: absolute; left: -99em;"></textarea>
        </div>
    
    </body>
    </html>
    

    只需将整个代码复制并粘贴到一个HTML文件中,然后尝试将(使用ctrl-v)文本从剪贴板粘贴到文档的任何位置。

    我在IE9和新版本的Firefox、Chrome和Opera中测试过它。效果相当好。另外,可以使用他喜欢的任何键组合来触发这个功能也是很好的。当然,不要忘记包含jquery源。

    请随意使用此代码,如果您有一些改进或问题,请将它们发回。另外请注意,我不是javascript开发人员,因此我可能错过了一些东西(=gt;做您自己的测试)。

        6
  •  10
  •   tmorell    11 年前

    基于 L2AelBA 安瑟尔这是在FF、Safari、Chrome、IE(8、9、10和11)上测试的。

        $("#editText").on("paste", function (e) {
            e.preventDefault();
    
            var text;
            var clp = (e.originalEvent || e).clipboardData;
            if (clp === undefined || clp === null) {
                text = window.clipboardData.getData("text") || "";
                if (text !== "") {
                    if (window.getSelection) {
                        var newNode = document.createElement("span");
                        newNode.innerHTML = text;
                        window.getSelection().getRangeAt(0).insertNode(newNode);
                    } else {
                        document.selection.createRange().pasteHTML(text);
                    }
                }
            } else {
                text = clp.getData('text/plain') || "";
                if (text !== "") {
                    document.execCommand('insertText', false, text);
                }
            }
        });
    
        7
  •  9
  •   AsgarAli    8 年前

    这个不使用任何setTimeout()。

    我已经用过 this 实现跨浏览器支持的优秀文章。

    $(document).on("focus", "input[type=text],textarea", function (e) {
        var t = e.target;
        if (!$(t).data("EventListenerSet")) {
            //get length of field before paste
            var keyup = function () {
                $(this).data("lastLength", $(this).val().length);
            };
            $(t).data("lastLength", $(t).val().length);
            //catch paste event
            var paste = function () {
                $(this).data("paste", 1);//Opera 11.11+
            };
            //process modified data, if paste occured
            var func = function () {
                if ($(this).data("paste")) {
                    alert(this.value.substr($(this).data("lastLength")));
                    $(this).data("paste", 0);
                    this.value = this.value.substr(0, $(this).data("lastLength"));
                    $(t).data("lastLength", $(t).val().length);
                }
            };
            if (window.addEventListener) {
                t.addEventListener('keyup', keyup, false);
                t.addEventListener('paste', paste, false);
                t.addEventListener('input', func, false);
            }
            else {//IE
                t.attachEvent('onkeyup', function () {
                    keyup.call(t);
                });
                t.attachEvent('onpaste', function () {
                    paste.call(t);
                });
                t.attachEvent('onpropertychange', function () {
                    func.call(t);
                });
            }
            $(t).data("EventListenerSet", 1);
        }
    }); 
    

    此代码在粘贴前使用选择手柄进行扩展: demo

        8
  •  5
  •   Matt Wonlaw    11 年前

    为了 清除粘贴的文本 用粘贴的文本替换当前选定的文本 事情很简单:

    <div id='div' contenteditable='true' onpaste='handlepaste(this, event)'>Paste</div>
    

    JS:

    function handlepaste(el, e) {
      document.execCommand('insertText', false, e.clipboardData.getData('text/plain'));
      e.preventDefault();
    }
    
        9
  •  5
  •   Community CDub    8 年前

    这应该适用于所有支持onPaste事件和突变观察者的浏览器。

    这个解决方案不仅仅是获取文本,它实际上允许您在粘贴到元素之前编辑粘贴的内容。

    它通过使用ContentEditable、OnPaste事件(所有主要浏览器都支持)en突变观察器(由Chrome、Firefox和IE11+支持)工作。

    步骤1

    创建内容可编辑的HTML元素

    <div contenteditable="true" id="target_paste_element"></div>
    

    步骤2

    在JavaScript代码中添加以下事件

    document.getElementById("target_paste_element").addEventListener("paste", pasteEventVerifierEditor.bind(window, pasteCallBack), false);
    

    我们需要绑定pastecallback,因为突变观察者将被异步调用。

    步骤3

    在代码中添加以下函数

    function pasteEventVerifierEditor(callback, e)
    {
       //is fired on a paste event. 
        //pastes content into another contenteditable div, mutation observer observes this, content get pasted, dom tree is copied and can be referenced through call back.
        //create temp div
        //save the caret position.
        savedCaret = saveSelection(document.getElementById("target_paste_element"));
    
        var tempDiv = document.createElement("div");
        tempDiv.id = "id_tempDiv_paste_editor";
        //tempDiv.style.display = "none";
        document.body.appendChild(tempDiv);
        tempDiv.contentEditable = "true";
    
        tempDiv.focus();
    
        //we have to wait for the change to occur.
        //attach a mutation observer
        if (window['MutationObserver'])
        {
            //this is new functionality
            //observer is present in firefox/chrome and IE11
            // select the target node
            // create an observer instance
            tempDiv.observer = new MutationObserver(pasteMutationObserver.bind(window, callback));
            // configuration of the observer:
            var config = { attributes: false, childList: true, characterData: true, subtree: true };
    
            // pass in the target node, as well as the observer options
            tempDiv.observer.observe(tempDiv, config);
    
        }   
    
    }
    
    
    
    function pasteMutationObserver(callback)
    {
    
        document.getElementById("id_tempDiv_paste_editor").observer.disconnect();
        delete document.getElementById("id_tempDiv_paste_editor").observer;
    
        if (callback)
        {
            //return the copied dom tree to the supplied callback.
            //copy to avoid closures.
            callback.apply(document.getElementById("id_tempDiv_paste_editor").cloneNode(true));
        }
        document.body.removeChild(document.getElementById("id_tempDiv_paste_editor"));
    
    }
    
    function pasteCallBack()
    {
        //paste the content into the element.
        restoreSelection(document.getElementById("target_paste_element"), savedCaret);
        delete savedCaret;
    
        pasteHtmlAtCaret(this.innerHTML, false, true);
    }   
    
    
    saveSelection = function(containerEl) {
    if (containerEl == document.activeElement)
    {
        var range = window.getSelection().getRangeAt(0);
        var preSelectionRange = range.cloneRange();
        preSelectionRange.selectNodeContents(containerEl);
        preSelectionRange.setEnd(range.startContainer, range.startOffset);
        var start = preSelectionRange.toString().length;
    
        return {
            start: start,
            end: start + range.toString().length
        };
    }
    };
    
    restoreSelection = function(containerEl, savedSel) {
        containerEl.focus();
        var charIndex = 0, range = document.createRange();
        range.setStart(containerEl, 0);
        range.collapse(true);
        var nodeStack = [containerEl], node, foundStart = false, stop = false;
    
        while (!stop && (node = nodeStack.pop())) {
            if (node.nodeType == 3) {
                var nextCharIndex = charIndex + node.length;
                if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
                    range.setStart(node, savedSel.start - charIndex);
                    foundStart = true;
                }
                if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
                    range.setEnd(node, savedSel.end - charIndex);
                    stop = true;
                }
                charIndex = nextCharIndex;
            } else {
                var i = node.childNodes.length;
                while (i--) {
                    nodeStack.push(node.childNodes[i]);
                }
            }
        }
    
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    }
    
    function pasteHtmlAtCaret(html, returnInNode, selectPastedContent) {
    //function written by Tim Down
    
    var sel, range;
    if (window.getSelection) {
        // IE9 and non-IE
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.deleteContents();
    
            // Range.createContextualFragment() would be useful here but is
            // only relatively recently standardized and is not supported in
            // some browsers (IE9, for one)
            var el = document.createElement("div");
            el.innerHTML = html;
            var frag = document.createDocumentFragment(), node, lastNode;
            while ( (node = el.firstChild) ) {
                lastNode = frag.appendChild(node);
            }
            var firstNode = frag.firstChild;
            range.insertNode(frag);
    
            // Preserve the selection
            if (lastNode) {
                range = range.cloneRange();
                if (returnInNode)
                {
                    range.setStart(lastNode, 0); //this part is edited, set caret inside pasted node.
                }
                else
                {
                    range.setStartAfter(lastNode); 
                }
                if (selectPastedContent) {
                    range.setStartBefore(firstNode);
                } else {
                    range.collapse(true);
                }
                sel.removeAllRanges();
                sel.addRange(range);
            }
        }
    } else if ( (sel = document.selection) && sel.type != "Control") {
        // IE < 9
        var originalRange = sel.createRange();
        originalRange.collapse(true);
        sel.createRange().pasteHTML(html);
        if (selectPastedContent) {
            range = sel.createRange();
            range.setEndPoint("StartToStart", originalRange);
            range.select();
        }
    }
    

    }

    代码的作用:

    1. 有人使用ctrl-v、contextmenu或其他方法触发粘贴事件
    2. 在粘贴事件中,将创建一个具有ContentEditable的新元素(具有ContentEditable的元素具有提升的权限)
    3. 将保存目标元素的插入符号位置。
    4. 焦点设置为新元素
    5. 内容被粘贴到新元素中,并在DOM中呈现。
    6. 突变观察者捕捉到了这一点(它记录了对DOM树和内容的所有更改)。然后触发突变事件。
    7. 粘贴内容的DOM被克隆到变量中并返回回调。临时元件被破坏。
    8. 回调接收克隆的DOM。插入符号已还原。您可以在将其附加到目标之前对其进行编辑。元素。在本例中,我使用TimDowns函数保存/恢复插入符号并将HTML粘贴到元素中。

    多谢 Tim Down 答案见本帖:

    Get the pasted content on document on paste event

        10
  •  4
  •   Lex Podgorny    11 年前

    适用于我的解决方案是,如果要粘贴到文本输入中,则添加事件侦听器来粘贴事件。 由于粘贴事件发生在输入文本更改之前,因此在我的on-paste处理程序中,我创建了一个延迟函数,在该函数中,我检查在粘贴时发生的输入框中的更改:

    onPaste: function() {
        var oThis = this;
        setTimeout(function() { // Defer until onPaste() is done
            console.log('paste', oThis.input.value);
            // Manipulate pasted input
        }, 1);
    }
    
        11
  •  4
  •   abligh    9 年前

    对尼科的回答发表评论太长了,我认为这在火狐上不再有效(根据评论),在Safari上也不再适用。

    首先,您现在似乎能够直接从剪贴板读取。而不是像这样的代码:

    if (/text\/plain/.test(e.clipboardData.types)) {
        // shouldn't this be writing to elem.value for text/plain anyway?
        elem.innerHTML = e.clipboardData.getData('text/plain');
    }
    

    用途:

    types = e.clipboardData.types;
    if (((types instanceof DOMStringList) && types.contains("text/plain")) ||
        (/text\/plain/.test(types))) {
        // shouldn't this be writing to elem.value for text/plain anyway?
        elem.innerHTML = e.clipboardData.getData('text/plain');
    }
    

    因为火狐有一个 types 字段是 DOMStringList 它不能实现 test .

    下一个Firefox将不允许粘贴,除非焦点位于 contenteditable=true 字段。

    最后,火狐不允许粘贴 可靠地 除非焦点在 textarea (或者可能是输入)这不仅是 contentEditable=真 而且:

    • display:none
    • visibility:hidden
    • 不是零大小

    我试图隐藏文本字段,以便在JSVNC仿真器上进行粘贴(即,它将指向远程客户机,实际上没有 特克斯塔利亚 等粘贴)。我发现,试图隐藏上面的文本字段时,有时会出现一些症状,但通常在第二次粘贴(或清除该字段以防止粘贴同一数据两次)时失败,因为该字段丢失了焦点,尽管 focus() . 我想到的解决办法是 z-order: -1000 使它 显示:无 ,使其为1px×1px,并将所有颜色设置为透明。讨厌。

    在Safari上,上述第二部分适用,即您需要 特克斯塔利亚 哪个不是 显示:无 .

        12
  •  3
  •   tDo    15 年前
        13
  •  2
  •   HoLyVieR    13 年前

    这对我很有用:

    function onPasteMe(currentData, maxLen) {
        // validate max length of pasted text
        var totalCharacterCount = window.clipboardData.getData('Text').length;
    }
    
    <input type="text" onPaste="return onPasteMe(this, 50);" />
    
        14
  •  2
  •   TomWan    10 年前

    这个解决方案是替换HTML标签,它是简单的跨浏览器;检查这个jfiddle: http://jsfiddle.net/tomwan/cbp1u2cx/1/ 核心代码:

    var $plainText = $("#plainText");
    var $linkOnly = $("#linkOnly");
    var $html = $("#html");
    
    $plainText.on('paste', function (e) {
        window.setTimeout(function () {
            $plainText.html(removeAllTags(replaceStyleAttr($plainText.html())));
        }, 0);
    });
    
    $linkOnly.on('paste', function (e) {
        window.setTimeout(function () {
            $linkOnly.html(removeTagsExcludeA(replaceStyleAttr($linkOnly.html())));
        }, 0);
    });
    
    function replaceStyleAttr (str) {
        return str.replace(/(<[\w\W]*?)(style)([\w\W]*?>)/g, function (a, b, c, d) {
            return b + 'style_replace' + d;
        });
    }
    
    function removeTagsExcludeA (str) {
        return str.replace(/<\/?((?!a)(\w+))\s*[\w\W]*?>/g, '');
    }
    
    function removeAllTags (str) {
        return str.replace(/<\/?(\w+)\s*[\w\W]*?>/g, '');
    }
    

    注意:您应该在后面做一些关于XSS过滤器的工作,因为这个解决方案不能过滤字符串,如“<<>”

        15
  •  1
  •   Peeyush    11 年前

    您可以这样做:

    将此jquery插件用于粘贴前和粘贴后事件:

    $.fn.pasteEvents = function( delay ) {
        if (delay == undefined) delay = 20;
        return $(this).each(function() {
            var $el = $(this);
            $el.on("paste", function() {
                $el.trigger("prepaste");
                setTimeout(function() { $el.trigger("postpaste"); }, delay);
            });
        });
    };
    

    现在您可以使用这个插件;:

    $('#txt').on("prepaste", function() { 
    
        $(this).find("*").each(function(){
    
            var tmp=new Date.getTime();
            $(this).data("uid",tmp);
        });
    
    
    }).pasteEvents();
    
    $('#txt').on("postpaste", function() { 
    
    
      $(this).find("*").each(function(){
    
         if(!$(this).data("uid")){
            $(this).removeClass();
              $(this).removeAttr("style id");
          }
        });
    }).pasteEvents();
    

    解释

    首先将所有现有元素的uid设置为数据属性。

    然后比较粘贴后的所有节点事件。因此,通过比较,您可以识别新插入的元素,因为它们将有一个uid,然后只需从新创建的元素中删除style/class/id属性,这样您就可以保留旧的格式。

        16
  •  1
  •   Roman Yudin    11 年前
    $('#dom').on('paste',function (e){
        setTimeout(function(){
            console.log(e.currentTarget.value);
        },0);
    });
    
        17
  •  1
  •   DaveAlger    10 年前

    只需让浏览器像往常一样在其内容可编辑的DIV中粘贴,然后在粘贴之后,将用于自定义文本样式的任何跨距元素与文本本身交换。在Internet Explorer和我尝试的其他浏览器中,这似乎工作正常…

    $('[contenteditable]').on('paste', function (e) {
        setTimeout(function () {
            $(e.target).children('span').each(function () {
                $(this).replaceWith($(this).text());
            });
        }, 0);
    });
    

    此解决方案假定您正在运行 JQuery 您不希望在任何内容中使用文本格式可编辑的分隔符 .

    好处是它非常简单。

        18
  •  1
  •   Ivan    10 年前
    function myFunct( e ){
        e.preventDefault();
    
        var pastedText = undefined;
        if( window.clipboardData && window.clipboardData.getData ){
        pastedText = window.clipboardData.getData('Text');
    } 
    else if( e.clipboardData && e.clipboardData.getData ){
        pastedText = e.clipboardData.getData('text/plain');
    }
    
    //work with text
    
    }
    document.onpaste = myFunct;
    
        19
  •  1
  •   kungfooman    7 年前

    简单解决方案:

    document.onpaste = function(e) {
        var pasted = e.clipboardData.getData('Text');
        console.log(pasted)
    }
    
        20
  •  0
  •   Ravi Selvaraj    7 年前

    这是上面发布的一个现有代码,但我已经为IE更新了它,错误是当选择并粘贴现有文本时,不会删除所选内容。这已由以下代码修复

    selRange.deleteContents(); 
    

    请参见下面的完整代码

    $('[contenteditable]').on('paste', function (e) {
        e.preventDefault();
    
        if (window.clipboardData) {
            content = window.clipboardData.getData('Text');        
            if (window.getSelection) {
                var selObj = window.getSelection();
                var selRange = selObj.getRangeAt(0);
                selRange.deleteContents();                
                selRange.insertNode(document.createTextNode(content));
            }
        } else if (e.originalEvent.clipboardData) {
            content = (e.originalEvent || e).clipboardData.getData('text/plain');
            document.execCommand('insertText', false, content);
        }        
    });