对于我工作中的内部工具,我试图拦截并覆盖 ctrl/cmd+c 快捷方式。
上下文:下面的脚本被添加到从我的应用程序导出的 html 文件中。其目的是确保当用户复制一段文本时,我的自定义标记会完全按原样写入剪贴板,而不会在正常复制文本时添加 Chrome 添加的任何样式元素。
从功能上来说,我希望它的工作方式与 ctrl/cmd+c 正常工作方式完全一样,以免破坏我同事的肌肉记忆工作流程。我们中的一些人使用 Mac,一些人使用 PC,但我们都使用 Chrome。
<script>
document.addEventListener('keydown', function (event) {
event.stopPropagation();
var selected ='';
var element = '';
if ((event.ctrlKey || event.metaKey) && (event.key === 'c' || event.key === 'C')) {
selected = window.getSelection();
if (selected != '') {
var selectedElement = document.createElement('div');
selectedElement.setAttribute('id','selection');
for (var i = 0, len = selected.rangeCount; i < len; ++i) {
selectedElement.appendChild(selected.getRangeAt(i).cloneContents());
}
document.getElementById('export').appendChild(selectedElement);
element = document.getElementById('selection');
} else { element = document.getElementById('export'); }
navigator.clipboard.write([new ClipboardItem({
'text/plain': new Blob([element.innerText], {type: 'text/plain'}),
'text/html': new Blob([element.innerHTML], {type: 'text/html'})
})])
document.getElementById('selection').remove();
}
});
</script>
keydown 事件侦听器正在检查 ctrl/cmd 与“c”/“C”的组合。触发时,脚本首先检查选择是否存在。如果是这样,所选文本将被克隆并附加到文档中,以使 Chrome 将其呈现为单独的 div 元素,然后写入剪贴板,然后再次删除。这似乎是一种迂回的做事方式,但这是我能找到的访问所选内容的innerText和innerHTML的唯一方法(通过暂时将所选内容变成它自己的div元素),并且它有效。
如果未选择任何内容,则包含整个文档的名为“export”的 div 元素将被写入剪贴板(我认为如果您想复制整个文本,能够跳过 ctrl/cmd+a 会很方便)。
无论如何,这一切都不重要。我的问题是该脚本每次都能在 PC 版 Chrome 上可靠地运行。但是当我在 Mac 上尝试时,快捷方式似乎在大约三分之二的时间里被忽略,即它没有被拦截,并且剪贴板内容是您在没有脚本的情况下获得的内容。真的很奇怪:我可以连续十次按下 cmd+c 并粘贴到剪贴板检查器中,结果是不可预测的。
为什么这样的东西只能在某些时候起作用?我究竟做错了什么? event.metaKey 是否已知不可靠?免责声明:我不是经验丰富的编码员,请保持温柔。 🥲
感谢使用 copy
事件和
preventDefault()
对此解决方案的评论中的 somethinghere!在 PC 和 Mac 上都可以使用。
<script>
document.addEventListener('copy', (event) => {
event.preventDefault();
var selected ='';
var element = '';
selected = window.getSelection();
if (selected != '') {
var selectedElement = document.createElement('div');
selectedElement.setAttribute('id','selection');
for (var i = 0, len = selected.rangeCount; i < len; ++i) {
selectedElement.appendChild(selected.getRangeAt(i).cloneContents());
}
document.getElementById('export').appendChild(selectedElement);
element = document.getElementById('selection');
} else { element = document.getElementById('export'); }
navigator.clipboard.write([new ClipboardItem({
'text/plain': new Blob([element.innerText], {type: 'text/plain'}),
'text/html': new Blob([element.innerHTML], {type: 'text/html'})
})])
document.getElementById('selection').remove();
});
</script>