【问题标题】:How to paste rich text from clipboard to HTML textarea element?如何将富文本从剪贴板粘贴到 HTML textarea 元素?
【发布时间】:2015-05-13 00:43:09
【问题描述】:

当从网络浏览器复制粘贴到文本处理器时,HTML 标记被转换为富文本,文本处理器尝试将标记转换为它自己的格式。这证明剪贴板能够保存标记。

在浏览器窗口之间复制粘贴(到普通的<textarea> 或其他元素)时,即使剪贴板中存在标记,标记也会被忽略。

也许有一种解决方案可以让浏览器从剪贴板中选择富文本格式。

有没有办法在<textarea> 元素中访问剪贴板的富文本?

换句话说,

必须在剪贴板某处的标记是否可以(因为剪贴板还不知道用户是粘贴到文本处理器还是网络浏览器中)粘贴为- 是否进入 HTTP POST 变量?

【问题讨论】:

  • 你试过了吗
  • 是的,我做了 - 我对问题进行了澄清

标签: javascript jquery html


【解决方案1】:

我一直在研究类似的问题:从桌面应用程序粘贴到浏览器时如何访问富文本格式标记。我找到了以下文章并找到了可以解决您的问题的解决方案,尽管在撰写本文时它还没有解决我自己的问题。

  1. https://www.lucidchart.com/techblog/2014/12/02/definitive-guide-copying-pasting-javascript/

  2. JavaScript get clipboard data on paste event (Cross browser)

如果您要查找的只是格式化的 html(浏览器为您解析富文本的结果),答案是访问 clipboardData 对象并将“html”传递给它参数而不是“文本”参数。参见下面的示例(只需将以下内容粘贴到名为 index.html 的文件中并在本地运行):

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

<script>
    document.addEventListener('paste', function(e) {
        e.preventDefault();
        
        var pastedText = ''

        if (window.clipboardData && window.clipboardData.getData) { // IE

            pastedText = window.clipboardData.getData('Text');

        } else if (e.clipboardData && e.clipboardData.getData) {

            pastedText = e.clipboardData.getData('text/html');

        }

        document.getElementById('target').innerHTML = pastedText
    });
</script>

上面的例子拆分了两个版本的clipboardData.getData(),一个用于IE,一个用于其他浏览器。粗略的流程是:先捕获paste事件,然后preventdefault,然后获取剪贴板数据为html,然后放到div中。这个示例的内容完全是从上面的两个链接中窃取的,但经过简化以排除我不需要的额外内容(即:隐藏输入以管理浏览器的焦点并支持“复制”和“剪切”事件)。应完全归功于这些文章的作者。

根据我的经验(使用 mac 和 chrome),将格式化文本(即使是删除线和缩进等晦涩的格式)粘贴到 #target div 会很好地保持原始格式。祝你好运!

现在,如果有人可以告诉我如何从剪贴板数据中获取实际富文本格式标签,请随时回答this question。谢谢!

【讨论】:

  • 我很确定如果您将 $("#target").html(pastedText); 更改为 $("#target").text(pastedText); 它应该可以正常工作。我做了一个类似的非 jquery 示例。当我设置元素的 innerHTML 时,它会格式化 html。当我设置元素的 innerText 时,它给了我标签。
【解决方案2】:

剪贴板包含“HTML 标记”的假设是不正确的。当您从浏览器(或使用多种剪贴板格式的窗口)复制时,该窗口会以尽可能多的格式提供数据。这包括富文本格式 (RTF) 和纯文本。 当您粘贴文本时,目标会选择它喜欢的内容或可以呈现的内容。因此,纯文本框将选择纯文本,而您的文字处理器将更喜欢富文本框,并且默认为纯文本副本。

编辑: 某些 浏览器(至少包括 Chrome > v.37)可能会在您将内容复制到剪贴板时添加源 HTML。这不是网络标准,因此不安全。

【讨论】:

  • 感谢您的解释。那么,我怎样才能访问 RTF 格式呢?如何让浏览器选择 RTF 而不是纯文本?
  • @Roland Seuhs,我认为 Flash 可能是您的解决方案,但“RTF 标记不会以任何方式解释或翻译”。 :help.adobe.com/en_US/as3/dev/…
  • 很伤心。当一个人粘贴到 Google-office 时会发生什么?也许他们已经找到了解决方案或解决方法。如果不是,我认为这是 Google-office 的一个主要限制。
  • @RolandSeuhs 你可以用contenteditable 属性创建一个div。这将使 DIV 可编辑,以便当用户将内容 粘贴 到其中时,它将选择 RTF 并将其 转换 为 HTML。因此,不能保证生成的 HTML 与执行复制的原始标记相匹配。请注意,我说的是“不保证”,但剪贴板中可能包含 HTML 副本,这取决于浏览器如何填充剪贴板。
  • 这演示了 contenteditable w3schools.com/tags/… 例如在 Chrome 中,如果您复制页面中的任何部分并粘贴到该 div 中,它将保留 HTML。这可能不是其他浏览器的标准。
【解决方案3】:

Google Office 确实支持 RichText 格式。从 IE 复制文本时,IE 以纯文本、富文本和 html 文本复制到剪贴板。所以从 IE 复制到 Google office 会显示富格式的文本。另一方面,FireFox 只复制纯文本和 html 文本格式的文本。所以任何不接受 HTML 格式文本的目标都会以纯文本形式显示文本。

【讨论】:

  • 有没有办法访问 html 文本缓冲区?
【解决方案4】:

我个人寻找一种解决方案,从剪贴板中抓取 rtf 并在此 jsbin 中进行管理:

console.log(event.clipboardData.types);
let paste = (event.clipboardData || window.clipboardData).getData('text/rtf');

用于在插入文本区域时分配内容而不转义(不要忘记更新 querySelector + html):

target.value=paste

还有其他类型,如文件或 html 可用。我是通过从 Excel 中复制来测试的。

【讨论】:

    【解决方案5】:

    感谢 Chris Chalmer 的出色回答,但是如何让它更完整一点呢? 我更愿意添加一些填充并获取代码...在 Edge、FF 和 Chrome 中测试并且即使在这里也可以使用 ;-)

    <div id="target" style="height: 75%;border:1px solid gray" contenteditable="true">Paste here...</div>
    <textarea style="height:25%;width: 100%;"></textarea>
    <script>
        document.addEventListener('paste', function(e) {
            e.preventDefault();
            
            var pastedText = ''
    
            if (window.clipboardData && window.clipboardData.getData) { // IE
    
                pastedText = window.clipboardData.getData('Text');
    
            } else if (e.clipboardData && e.clipboardData.getData) {
    
                pastedText = e.clipboardData.getData('text/html');
    
            }
    
            var tmp1 = ["<div style=\"", "</div>"];
            var tmp2 = [pastedText.indexOf(tmp1[0]) + tmp1[0].length, pastedText.lastIndexOf(tmp1[1])];
            pastedText = tmp1[0] + "padding:8px;" + pastedText.substr(tmp2[0], tmp2[1] - tmp2[0]);
            tmp1 = document.getElementById('target');
            tmp1.innerHTML = pastedText;
            tmp1.nextElementSibling.value = pastedText;
        });
    </script>

    【讨论】:

    • VSC 代码默认是这样的 \r\n\r\n
    猜你喜欢
    • 2019-10-26
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    相关资源
    最近更新 更多