网页复制,前几天用户反馈一个bug,说复制不了,然后也不能手动长按复制。
我排查了问题,发现
有些浏览器不支持一键复制的,然后又因为input文本框加上了readonly属性,导致了不能手动选择复制。
下面代码已经完美的解决了这些用户的问题,如果不能复制,那么点击和长按事件后就是全选文本框的内容了。
点击,不用说是click。 长按事件,我是取巧,用了touchend事件。
我不善表达,那么,废话不多说,直接上代码,比起废话连篇的理论,我更推崇的是实际代码。
一、clipboard插件版(这里用的外链js文件是cdn文件,如若失效,可自行下载一个clipboard.js),我比较推崇,因为别人插件都测试了不知道多少遍了,经历了考验,插件虽大,但老板看不到代码,看老板关心bug还是关心文件大小吧。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>js复制(插件版)--如若不能复制,长按可以直接选择全部复制</title> <style> html,body{ padding:0; margin: 0; } *{ -webkit-box-sizing: border-box; box-sizing: border-box; } .box{ border:1px solid #000; /*padding: 10px 0 30px 10px;*/ padding:10px; } input{ 100%; /*height: 20px;*/ text-indent:2px; display: block; margin: 1em 0; font-size:14px; } .fs-12{ font-size: 12px; display: block; } .btn{ display: block; margin-top: 10px; } textarea{ 200px; height: 200px; margin-top: 10px; text-indent:2px; } </style> </head> <body> <h1>js复制(插件版)--如若不能复制,长按可以直接选择全部复制</h1> <div class="box"> <h3>input版本</h3> <input type="text" value="复制我这一行的数据" readonly id="foo" onclick="selectText('foo')" ontouchend="selectText('foo')"> <em class="fs-12">如复制失败,请选择长按复制</em> <button class="btn" data-clipboard-action="copy" data-clipboard-target="#foo" onclick="">复制</button> <textarea placeholder="粘贴看看复制对不对"></textarea> </div> <div class="box"> <h3>没有input版本</h3> <p id="p" onclick="selectText('p')" ontouchend="selectText('p')">复制我这一行的数据</p> <em class="fs-12">如复制失败,请选择长按复制</em> <button data-clipboard-text="复制我这一行的数据" class="btn" onclick="">复制</button> <textarea placeholder="粘贴看看复制对不对"></textarea> </div> <script type='text/javascript' src="https://cdn.staticfile.org/clipboard.js/1.5.15/clipboard.min.js"></script> <script> /* * input版本 * 不用input版本 * * js代码都一致 * */ var clipboard = new Clipboard('.btn'); clipboard.on('success', function(e) { alert("复制成功") }); clipboard.on('error', function(e) { alert("复制失败,请选择长按复制") }); /* * touchend事件是为了移动端全选的 * */ function selectText(id){ var text = document.getElementById(id); let tag = text.tagName.toLocaleLowerCase(); if(tag == 'input' || tag =='textarea') { text.select(); return } if (document.body.createTextRange) { var range = document.body.createTextRange(); range.moveToElementText(text); range.select(); } else if (window.getSelection) { var selection = window.getSelection(); var range = document.createRange(); range.selectNodeContents(text); selection.removeAllRanges(); selection.addRange(range); /*if(selection.setBaseAndExtent){ selection.setBaseAndExtent(text, 0, text, 1); }*/ } else { // alert("none"); console.log('因为兼容,不能选择'); } } </script> </body> </html>
二、原生js版,( 亲测,Firefox 48.0、Chrome 60.0、IE 8 都能用) ,但是没经历过市场考验,我公司的代码都是用上面插件那一套,不敢用这一套(ps:因为公司后台服务器因访问量崩了,我就不触眉头了,有没有bug,才是我现在的这个老板要关心的问题)。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>js复制(原生)--如若不能复制,长按可以直接选择全部复制</title> <style> html,body{ padding:0; margin: 0; } *{ -webkit-box-sizing: border-box; box-sizing: border-box; } .box{ border:1px solid #000; /*padding: 10px 0 30px 10px;*/ padding:10px; } input{ width: 100%; /*height: 20px;*/ text-indent:2px; display: block; margin: 1em 0; font-size:14px; } .fs-12{ font-size: 12px; display: block; } .btn{ display: block; margin-top: 10px; } textarea{ width: 200px; height: 200px; margin-top: 10px; text-indent:2px; } </style> </head> <body> <h1>js复制(原生)--如若不能复制,长按可以直接选择全部复制</h1> <div class="box"> <h3>input版本</h3> <input type="text" value="复制我这一行的数据" readonly id="foo" onclick="selectText('foo')" ontouchend="selectText('foo')"> <em class="fs-12">如复制失败,请选择长按复制</em> <button class="btn" onclick="copy('foo')">复制</button> <textarea placeholder="粘贴看看复制对不对"></textarea> </div> <div class="box"> <h3>没有input版本</h3> <p id="p" onclick="selectText('p')" ontouchend="selectText('p')">复制我这一行的数据</p> <em class="fs-12">如复制失败,请选择长按复制</em> <button class="btn" onclick="copy('p')">复制</button> <textarea placeholder="粘贴看看复制对不对"></textarea> </div> <script> /* * 亲测,Firefox 48.0,Chrome 60.0,IE 8 都能用 * */ /* * 一、原理剖析 * * 浏览器提供了copy命令 复制选中的文本 * * input 和 textarea可以直接选中文本 ,也就是document.select() * div 、p、span等标签,则不能直接选中, 下面有个函数,selectText * * */ function copy(id){ selectText(id); try{ document.execCommand("copy"); alert("复制成功"); } catch(err) { alert("复制失败,请选择长按复制") } } /* * touchend事件是为了移动端全选的 * selectText * 选择文本 * */ function selectText(id){ var text = document.getElementById(id); let tag = text.tagName.toLocaleLowerCase(); if(tag == 'input' || tag =='textarea') { text.select(); return } if (document.body.createTextRange) { var range = document.body.createTextRange(); range.moveToElementText(text); range.select(); } else if (window.getSelection) { var selection = window.getSelection(); var range = document.createRange(); range.selectNodeContents(text); selection.removeAllRanges(); selection.addRange(range); /*if(selection.setBaseAndExtent){ selection.setBaseAndExtent(text, 0, text, 1); }*/ } else { // alert("none"); console.log('因为兼容,不能选择'); } } </script> </body> </html>