在javascript中从剪贴板获取html

发布于 2024-08-31 11:03:25 字数 728 浏览 5 评论 0原文

我需要实现 RichTextEditors 非常常见的功能 - 从剪贴板中获取 HTML 。 任何人都可以帮助指导如何解决此任务吗?

它必须是跨平台的(IE、FF、Chrome、Opera)。 我刚刚从这段代码开始:

<script type="text/javascript">
    $('.historyText').live('input paste', function(e) {

        var paste = e.clipboardData && e.clipboardData.getData ?
        e.clipboardData.getData('text/plain') :                // Standard
        window.clipboardData && window.clipboardData.getData ?
        window.clipboardData.getData('Text') :                 // MS
        false;

        alert(paste);
    });</script>

window.clipboardData 和 e.clipboardData 均为 null(Chrome、Firefox)。

更新:用户想要从其他浏览器窗口粘贴文章内容,我需要获取 html 标签。

I need to implement task which is quite common feature for RichTextEditors - take HTML from clipboard.
Can anyone help with guide on how to solve this task?

It has to be cross platform (IE, FF, Chrome, Opera).
I just started from this code:

<script type="text/javascript">
    $('.historyText').live('input paste', function(e) {

        var paste = e.clipboardData && e.clipboardData.getData ?
        e.clipboardData.getData('text/plain') :                // Standard
        window.clipboardData && window.clipboardData.getData ?
        window.clipboardData.getData('Text') :                 // MS
        false;

        alert(paste);
    });</script>

Both window.clipboardData and e.clipboardData are null (Chrome, Firefox).

Update: User wants to paste article content from other browser windows, and I need to get html tags.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你如我软肋 2024-09-07 11:03:25

我实际上已经在这方面做了很多工作,刚刚写了一个 不错的博客文章描述了我们如何在 Lucidchart 详细地做到这一点(作为免责声明,我在 Lucidchart 工作)。我们有 一个 JSFiddle,可以显示复制和粘贴(在 Firefox、Safari、Chrome 和 IE9+ 中测试)。

简而言之,您需要在系统粘贴事件期间获取 HTML。在大多数(非 IE)浏览器中,这可以通过如下简单的操作来完成:

document.addEventListener('paste', function(e) {
  var html = e.clipboardData.getData('text/html');
  // Whatever you want to do with the html
}

问题是当您想在 IE 中获取 HTML 时。无论出于何种原因,IE 都无法通过 JavaScript 访问文本/html 剪贴板数据。你要做的就是让浏览器粘贴到一个contenteditable div,然后在粘贴事件结束后获取html。

<div id="ie-clipboard-contenteditable" class="hidden" contenteditable="true"></div>
var ieClipboardDiv = $('#ie-clipboard-contenteditable'); 

var focusIeClipboardDiv = function() {
  ieClipboardDiv.focus();
  var range = document.createRange();
  range.selectNodeContents((ieClipboardDiv.get(0)));
  var selection = window.getSelection();
  selection.removeAllRanges();
  selection.addRange(range);
};

document.addEventListener('beforepaste', function() {
  if (hiddenInput.is(':focus')) {
    focusIeClipboardDiv();
  }
}, true);

document.addEventListener('paste', function(e) {
  ieClipboardDiv.empty();
  setTimeout(function() {
    var html = ieClipboardDiv.html();
    // Do whatever you want with the html
    ieClipboardDiv.empty();
    // Return focus here
  }, 0);
}

I actually have done a lot of work on this, and just wrote a nice blog post describing how we did it in detail at Lucidchart (as a disclaimer, I work at Lucidchart). We have a JSFiddle that shows copying and pasting (tested in Firefox, Safari, Chrome, and IE9+).

The short of the answer is that you will need to get the HTML during the system paste event. In most (non-IE) browsers, this can be done with something as simple as the following:

document.addEventListener('paste', function(e) {
  var html = e.clipboardData.getData('text/html');
  // Whatever you want to do with the html
}

The problem is when you want to get HTML in IE. For whatever reason, IE doesn't make the text/html clipboard data accessible via javascript. What you have to do is let the browser paste to a contenteditable div and then get the html after the paste event is over.

<div id="ie-clipboard-contenteditable" class="hidden" contenteditable="true"></div>
var ieClipboardDiv = $('#ie-clipboard-contenteditable'); 

var focusIeClipboardDiv = function() {
  ieClipboardDiv.focus();
  var range = document.createRange();
  range.selectNodeContents((ieClipboardDiv.get(0)));
  var selection = window.getSelection();
  selection.removeAllRanges();
  selection.addRange(range);
};

document.addEventListener('beforepaste', function() {
  if (hiddenInput.is(':focus')) {
    focusIeClipboardDiv();
  }
}, true);

document.addEventListener('paste', function(e) {
  ieClipboardDiv.empty();
  setTimeout(function() {
    var html = ieClipboardDiv.html();
    // Do whatever you want with the html
    ieClipboardDiv.empty();
    // Return focus here
  }, 0);
}
恍梦境° 2024-09-07 11:03:25

您将无法单独使用 JavaScript 从剪贴板获取数据,而这本来就是应该的方式。当前版本的 TinyMCE 和 CKEditor 执行此操作的方式如下:

  1. 使用按键事件处理程序检测 ctrl-v / shift-ins 事件
  2. 在该处理程序中,保存当前用户选择,在屏幕外添加一个 div 元素(如左侧) -1000px) 到文档,将插入符号移动到该 div 内部,从而有效地重定向粘贴
  3. 在事件处理程序中设置一个非常短的计时器(例如 1 毫秒),以调用另一个从 div 检索 HTML 内容并执行任何操作的函数需要处理时,从文档中删除 div,恢复用户选择并插入处理后的 HTML。

请注意,这仅适用于键盘粘贴事件,不适用于从上下文或编辑菜单进行粘贴。当粘贴事件触发时,将插入符号重定向到 div 中已经太晚了(至少在某些浏览器中)。

You won't be able to get data from the clipboard using JavaScript alone, which is the way it should be. The way current versions of TinyMCE and CKEditor do this is as follows:

  1. Detect a ctrl-v / shift-ins event using a keypress event handler
  2. In that handler, save the current user selection, add a div element off-screen (say at left -1000px) to the document, move the caret to be inside that div, thus effectively redirecting the paste
  3. Set a very brief timer (say 1 millisecond) in the event handler to call another function that retrieves the HTML content from the div and does whatever processing is required, removes the div from the document, restores the user selection and inserts the processed HTML.

Note that this will only work for keyboard paste events and not pastes from the context or edit menus. By the time the paste event fires, it's too late to redirect the caret into the div (in some browsers, at least).

夜吻♂芭芘 2024-09-07 11:03:25

在 Chrome 中,我使用以下代码通过事件访问 ClipboardData:

$(document).bind('paste', function(e) {
    var clipboardData = e.originalEvent.clipboardData;
});

In Chrome, I access clipboardData through the event using this code:

$(document).bind('paste', function(e) {
    var clipboardData = e.originalEvent.clipboardData;
});
败给现实 2024-09-07 11:03:25

这段代码为我完成了这项工作。

setTimeout(() => {
  navigator.clipboard.read()
    .then(text => {
        for (const item of text) {
            console.log('content type:', item.types);
            const blob = item.getType(item.types[0]).then(
                blob => {
                    const reader = new FileReader();
                    reader.onload = function(event) {
                        console.log('result:\n', event.target.result);
                    };
                    reader.readAsText(blob);
                },
                err => {
                    console.error('Failed to read clipboard content: ', err);
                }
            );
        }
    })
    .catch(err => {
      console.error('Failed to read clipboard contents: ', err);
    });
}, 3000);

有两件事要记住。

  • 此代码在浏览器控制台中
  • 运行在控制台中运行代码后,我们必须单击浏览器窗口中的某个位置以获得焦点或按 Tab 键。 参考

This piece of code did the job for me.

setTimeout(() => {
  navigator.clipboard.read()
    .then(text => {
        for (const item of text) {
            console.log('content type:', item.types);
            const blob = item.getType(item.types[0]).then(
                blob => {
                    const reader = new FileReader();
                    reader.onload = function(event) {
                        console.log('result:\n', event.target.result);
                    };
                    reader.readAsText(blob);
                },
                err => {
                    console.error('Failed to read clipboard content: ', err);
                }
            );
        }
    })
    .catch(err => {
      console.error('Failed to read clipboard contents: ', err);
    });
}, 3000);

2 things to keep in mind.

  • this code works in the browser console
  • After running the code in the console, we will have to click somewhere in the browser window for the focus or press tab. reference
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文