复制--插件版,js原生版本

网页复制,前几天用户反馈一个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>
View Code

二、原生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>
View Code
原文地址:https://www.cnblogs.com/huoan/p/8899947.html