避免使用单独的文档节点来进行撤消/重做操作-可能吗?

时间:2019-04-11 12:24:24

标签: javascript google-chrome-extension

我正在使用一个Chrome扩展程序,该扩展程序应该清除页面上当前所选文本的所有格式。该脚本是使用oncut和oncopy触发的,这意味着它应该在用户从页面剪切或复制文本时触发。

为此,我正在使用以下trick

  1. 在“浏览器视图”之外创建一个空的文本区域,使其不可见
  2. 使用window.getSelection()。toString()获取当前选择的文本,删除流程中的所有格式
  3. 将所选文本放入不可见的文本区域,然后使用.select()突出显示它
  4. 使用document.execCommand(“ copy”)
  5. 复制突出显示的文本
  6. 删除不可见的文本区域

我几乎可以像使用各种变通办法来纠正某些缺陷一样工作,例如丢失原始选择或剪切功能无法正确剪切。但是,目前阻碍我执行脚本的最大缺陷是,它完全破坏了浏览器的撤消和重做功能。用我的脚本剪切的内容无法撤消。

我的想法是在单独的文档节点中完成整个文本清理业务,这样我就不会弄乱浏览器的撤消和重做功能。我认为,然后可以在不影响实际页面的其他文档节点中简单地执行所有这些操作。那可能吗?还是我的问题有更简单的解决方案?

1 个答案:

答案 0 :(得分:0)

关注有关.getData()无效的最后一条评论:

@SynnKo,.getData()对复制事件不起作用是正确的。但是,如复制事件页面https://developer.mozilla.org/en-US/docs/Web/API/Element/copy_event上的示例所示,复制事件实际上并不需要.getData()。只需使用.setData()方法即可更改要复制到已清理版本中的内容。

由于用户必须先选择一些文本才能实际复制所选内容,因此您可以使用.getSelection()来获取将被事件复制的选择并进行更改。

以下代码在Chrome浏览器中非常适合我。 如果我输入文本区域,然后选择/突出显示一些文本,然后执行复制命令,则会在剪贴板上得到更新的文本,因此可以将其粘贴到其他位置。

const source = document.querySelector( '#sourcetest' );
const output = document.querySelector( '#copytest' );
source.addEventListener( 'copy', event => {
  const selection = document.getSelection();
  const updated = selection + ' - updated by setData()';
  // Writing the text back into a textarea is not needed for anything.
  // Just showing it that it is possible.
  // The reason the article uses it, is to use execCommand('copy')
  // Because textareas are an element that supports entitiy encoding.
  // Stuff like \n\r\t for newlines and tabs and such.
  // Which is harder to do in a contenteditable element.
  output.innerHTML = updated;
  // If you paste after copying, you'll see that the update succeeded
  event.clipboardData.setData( 'text/plain', updated );
  // Important to cancel the event. Else the default behaviour will overwrite our setData() with the original text again.
  event.preventDefault();
});
<textarea id="sourcetest"></textarea>
<textarea id="copytest"></textarea>