很多网站、博客,论坛都会需要复制的功能,js如何实现复制功能呢?
比如我的博客,我的博客当时在编写的时候遇到了一个问题,就是代码块复制的问题
起初我用的是 Clipboard.js 实现代码块复制,当时也不是太了解
而且如果我有多个代码块的话,它不会随着我点击的代码块复制,而是只会复制整个页面出现的第一个代码块
最后我判断当鼠标移动到当前代码块上时,给代码块添加一个Clipboard
属性(这个是可自定义的),然后使用document.querySelector
获取元素进行复制(得到元素后将元素给Clipboard.js进行复制即可)随后当鼠标移出时,移除Clipboard
属性(具体代码如下)
当时用的是Jquery写的,原生JS的话可以用onmouseenter
(移入)和onmouseleave
(移出)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
$(".highlight-wrap").hover( function() { $("[Clipboard]").removeAttr("Clipboard"); $(this).find(".code").attr("Clipboard", ""); } );
var clipboard = new ClipboardJS('.clipboard', { target: function() { return document.querySelector("[Clipboard]"); } });
clipboard.on('success', function(event) { event.trigger.innerHTML = "<i class='fa fa-check' style='color:green'></i>"; setTimeout(function () { event.trigger.innerHTML = "<i class='fa fa-clipboard'></i>" }, 2000) event.clearSelection(); });
clipboard.on('error', function(event) { event.trigger.innerHTML = "<i class='fa fa-times' style='color:red'></i>"; setTimeout(function () { event.trigger.innerHTML = "<i class='fa fa-clipboard'></i>" }, 2000) });
|
后来我决定对我的博客主题下手,整个框架大换血,移除掉Jquery,全部改用原生JS处理
原生JS实现复制文本内容的主要代码
1 2 3 4 5 6 7
|
const selection = window.getSelection() selection.selectAllChildren(document.querySelector(".code")) document.execCommand("Copy"); selection.removeAllRanges()
|
复制代码块的完整代码,足足比Clipboard.js
代码量少了一大截,而且不需要引入外部js
Clipboard.js库大小:
未压缩:25.5kb
已压缩:8.82kb
gzip:3kb (官方描述的3kb,我未验证过)
自己用原生JS写的关键代码才4行,如果写完整代码且复杂的高的也不会超过20行
下面是我博客代码块复制功能的完整代码
问:为什么不用onmouseenter
进行鼠标移入添加属性了?
答: 不想频繁添加删除属性操作就用循环了,至于这两个哪个更快我没研究过,
使用onmouseenter
还是for循环的话,因人而异吧,想用哪种方式就用哪种方式,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| CodeCopy() function CodeCopy(){ document.querySelectorAll(".highlight-wrap").forEach(function (item) { item.firstChild.onclick = function () { const selection = window.getSelection() selection.selectAllChildren(item.querySelector(".code")) document.execCommand("Copy"); selection.removeAllRanges()
item.firstChild.innerHTML = "<i class='fa fa-check' style='color:green'></i>"; setTimeout(function () { item.firstChild.innerHTML = "<i class='fa fa-clipboard'></i>" }, 2000) } }) }
|
代码块html结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <div class="highlight-wrap" data-rel="Js"> <span class="clipboard"> <i class="fa fa-clipboard"></i> </span> <figure class="iseeu highlight js"> <table> <tr> <td class="gutter"> <pre> <span class="line">1</span> <br> <span class="line">2</span> <br> <span class="line">3</span> <br> .... </pre> </td> <td class="code"> <pre> <span class="line"></span> <br> <span class="line">CodeCopy()</span> <br> <span class="line"> <span class="function"> <span class="keyword">function</span> <span class="title">CodeCopy</span> (<span class="params"></span> ) </span> { </span> </pre> </td> </tr> </table> </figure> </div>
|