gpt4 book ai didi

JavaScript 在粘贴事件中获取剪贴板数据(跨浏览器)

转载 作者:搜寻专家 更新时间:2023-11-01 04:42:48 24 4
gpt4 key购买 nike

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

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

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

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

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

最佳答案

解决方案 #1(仅纯文本且需要 Firefox 22+)

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

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

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);
<div id='editableDiv' contenteditable='true'>Paste</div>

JSFiddle

请注意,此解决方案为 getData 函数使用参数“Text”,这是非标准的。但是,在撰写本文时,它适用于所有浏览器。


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

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

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);
}
<div id='div' contenteditable='true'>Paste</div>

JSFiddle

说明

divonpaste 事件附加了 handlePaste 函数并传递了一个参数:event 粘贴事件的对象。我们特别感兴趣的是此事件的 clipboardData 属性,它允许在非 ie 浏览器中访问剪贴板。在 IE 中,等效项是 window.clipboardData,尽管它的 API 略有不同。

请参阅下面的资源部分。


handlepaste 函数:

这个函数有两个分支。

首先检查 event.clipboardData 是否存在,并检查它的 types 属性是否包含 'text/html'(types 可能是使用 contains 方法检查的 DOMStringList 或使用 indexOf 方法检查的字符串)。如果满足所有这些条件,那么我们将按照解决方案 #1 进行操作,除了使用“text/html”而不是“text/plain”。这目前适用于 Chrome 和 Firefox 22+。

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

  1. 将元素的内容保存到 DocumentFragment
  2. 清空元素
  3. 调用waitForPastedData函数

waitforpastedata 函数:

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

  1. 将可编辑的 div(现在是粘贴的数据)的 innerHTML 保存到一个变量
  2. 恢复DocumentFragment中保存的内容
  3. 使用检索到的数据调用“processPaste”函数

processpaste 函数:

对粘贴的数据做任意事情。在这种情况下,我们只是提醒数据,你可以做任何你想做的事。您可能希望通过某种数据清理过程来运行粘贴的数据。


保存和恢复光标位置

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

MDN 上的资源

感谢Tim Down建议使用 DocumentFragment,并能够在 Firefox 中捕获由于使用 DOMStringList 而不是 clipboardData.types 的字符串而导致的错误

关于JavaScript 在粘贴事件中获取剪贴板数据(跨浏览器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8186397/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com