有没有办法在javascript中将html字符串(即xx
)复制到剪贴板中作为text/html,以便可以将其粘贴到例如带格式的gmail邮件中(即xx以粗体显示)
存在以文本(文本/纯文本)形式复制到剪贴板的解决方案,例如/sf/ask/17360801/,但不是text/html
我需要一个非闪存,非jquery解决方案,至少可以在IE11 FF42和Chrome上运行.
理想情况下,我想在剪贴板中存储字符串的text和html版本,以便可以粘贴正确的版本,具体取决于目标是否支持html.
由于这个答案得到了一些关注,我已经完全重写了凌乱的原创,以便更容易掌握.如果您想查看修订前的版本,可以在此处找到它.
简而言之的问题:
我可以使用JavaScript将某些HTML代码的格式化输出复制到用户剪贴板吗?
回答:
是的,有一些限制,你可以.
解:
下面是一个完全可以完成的功能.我用你需要的浏览器测试它,它适用于所有浏览器.但是,IE 11将要求确认该操作.
解释如何工作可以在下面找到,你可以在这个jsFiddle中交互式测试函数.
// This function expects an HTML string and copies it as rich text. function copyFormatted (html) { // Create container for the HTML // [1] var container = document.createElement('div') container.innerHTML = html // Hide element // [2] container.style.position = 'fixed' container.style.pointerEvents = 'none' container.style.opacity = 0 // Detect all style sheets of the page var activeSheets = Array.prototype.slice.call(document.styleSheets) .filter(function (sheet) { return !sheet.disabled }) // Mount the container to the DOM to make `contentWindow` available // [3] document.body.appendChild(container) // Copy to clipboard // [4] window.getSelection().removeAllRanges() var range = document.createRange() range.selectNode(container) window.getSelection().addRange(range) // [5.1] document.execCommand('copy') // [5.2] for (var i = 0; i < activeSheets.length; i++) activeSheets[i].disabled = true // [5.3] document.execCommand('copy') // [5.4] for (var i = 0; i < activeSheets.length; i++) activeSheets[i].disabled = false // Remove the container // [6] document.body.removeChild(container) }
说明:
查看上面代码中的注释,以查看您在以下过程中的当前位置:
我们创建了一个容器来放入我们的HTML代码.
我们将容器的样式设置为隐藏,并检测页面的活动样式表.原因很快就会解释.
我们将容器放入页面的DOM中.
我们删除可能存在的选择并选择容器的内容.
我们自己进行复制.这实际上是一个多步骤的过程:Chrome将使用应用的CSS样式复制文本,而其他浏览器将使用浏览器的默认样式复制它.因此,我们将在复制之前禁用所有用户样式,以获得最一致的结果.
在我们这样做之前,我们过早地执行copy
命令.这是IE11的黑客攻击:在此浏览器中,必须手动确认一次复制.在用户单击"确认"按钮之前,IE用户将看到没有任何样式的页面.为避免这种情况,我们首先复制,等待确认,然后禁用样式并再次复制.那个时候我们不会得到确认对话,因为IE记得我们的最后选择.
我们实际上禁用了页面的样式.
现在我们copy
再次执行命令.
我们重新启用样式表.
我们从页面的DOM中删除容器.
我们已经完成了.
注意事项:
格式化的内容在浏览器中不会完全一致.
如上所述,Chrome(即Blink引擎)将采用与Firefox和IE不同的策略:Chrome将使用CSS样式复制内容,但省略任何未定义的样式.
另一方面,Firefox和IE将不会应用特定于页面的CSS,它们将应用浏览器的默认样式.这也意味着它们会应用一些奇怪的样式,例如默认字体(通常是Times New Roman).
出于安全原因,浏览器只允许该功能作为用户交互的效果执行(例如点击,按键等)