网页实现把文本复制到粘贴板

思路整理

有一个按钮可以触发以下逻辑:

  • 将生成的文本自动复制到剪切板上 结果要有友好提示
  • 复制成功后可以粘贴到任何地方

一开始我以为有通用的接口,一番调研之后发现有以下几种东东:

  1. document.execCommand("copy")这个用于在要复制的文本处于被选中状态时使用
  2. window.clipboardData.setData("Text", clipBoardContent)为挂载在window上的API 据说兼容性不好
  3. 结合ZeroClipboard.js这个插件实现兼容性比较好的复制粘贴,通过new ZeroClipboard.client()来调用各个方法
  4. github上的库clipboard.js,通过new Clipboard('.btn')这种语法实现访问剪切板的操作,兼容性最好

有一些具体的代码示例参考CSDN中的内容,不过要考虑是否过时

由于是在vue框架基础上进行开发,最后选择了上面提到的第四种方法,完全抛弃了flash的hack实现(第三种),并且有着强大的兼容性,github上的star数量已经说明了一切,本来考虑是自己封装个指令来用,后来发现vue-clipboard2这个插件已经实现了封装,按照绝不重复造轮子的原则,直接在项目里用了起来。

原理剖析

clipboard.js的核心原理是虚拟了一个不可见的选区并利用复制的API来实现文本复制,因此最起码需要动态创造的页面元素有可以有被选中的属性。 为了方便学习vue自定义指令的写法,现在把vue-clipboard2的代码摘抄过来加以学习:

var Clipboard = require('clipboard')

var VueClipboard = {
  install: function (Vue) {
    Vue.prototype.$copyText = function (text) { 
      // 这个是非触发式的调用api(this.$copyText)
      return new Promise(function (resolve, reject) {
        var fake_el = document.createElement('button');
        var clipboard = new Clipboard(fake_el, {
          text: function () { return text },
          action: function () { return 'copy' }
        });
        clipboard.on('success', function (e) {
          clipboard.destroy();
          resolve(e);
        });
        clipboard.on('error', function (e) {
          clipboard.destroy();
          reject(e);
        });
        fake_el.click();
      });
    };
    // 自定义指令时要注意vue自定义指令的生命周期
    Vue.directive('clipboard', {
      bind: function (el, binding, vnode) {
        if(binding.arg === 'success') {
          el._v_clipboard_success = binding.value
        } else if(binding.arg === 'error') {
          el._v_clipboard_error = binding.value
        } else {
          var clipboard = new Clipboard(el, {
            text: function () { return binding.value },
            action: function () { return binding.arg === 'cut' ? 'cut' : 'copy' }
          })
          clipboard.on('success', function (e) {
            var callback = el._v_clipboard_success
            callback && callback(e)
          })
          clipboard.on('error', function (e) {
            var callback = el._v_clipboard_error
            callback && callback(e)
          })
          el._v_clipboard = clipboard
        }
      },
      update: function (el, binding) {
        if(binding.arg === 'success') {
          el._v_clipboard_success = binding.value
        } else if(binding.arg === 'error') {
          el._v_clipboard_error = binding.value
        } else {
          el._v_clipboard.text = function () { return binding.value }
          el._v_clipboard.action = function () { return binding.arg === 'cut' ? 'cut':'copy'}
        }
      },
      unbind: function (el, binding) {
        if(binding.arg === 'success') {
          delete el._v_clipboard_success
        } else if(binding.arg === 'error') {
          delete el._v_clipboard_error
        } else {
          el._v_clipboard.destroy()
          delete el._v_clipboard
        }
      }
    })
  }
}

// 以下是把这个模块输出的写法,兼容了amd/cmd
if (typeof exports == "object") {
  module.exports = VueClipboard
} else if (typeof define == "function" && define.amd) {
  define([], function() {
    return VueClipboard
  })
}

插件使用

如果对vue-directive比较熟悉的话,这些看懂都比较容易,核心就是new Clipboard()的调用,看完之后在vue中的用法自然很容易。定义的指令名为v-clipboard。并且可以传入v-clipboard:cut/v-clipboard:copy/v-clipboard:success/v-clipboard:error等参数及回调函数。

<el-button v-clipboard:copy="finalLink" v-clipboard:success="copySuccess" 
 v-clipboard:error="copyFail" type="primary">复制链接</el-button>
import Vue from 'vue'
import VueClipboard from 'vue-clipboard2'
Vue.use(VueClipboard) //使用自定义指令的写法
...
copySuccess() {
    this.$message({
        message: '链接已复制,请粘贴',
        type: 'success'
    })
},
copyFail() {
    this.$message.error('复制失败,请手动操作')
}
...

element-ui基础上开发而成,所以成功和失败的回调都直接用了elementAPI。相信还是比较容易看懂的哈~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据小魔方

R语言笔记之——常用数据导入方式简介

因为之前旁听过几节R语言的课程,再加上自己练习数据可视化的需要(特别是可视化包——“ggplot2”),学了些R语言的皮毛。 总觉得基础没打牢,好高骛远、急于求...

34070
来自专栏向治洪

Vue.js快速入门

Vue.js简介 Vue.js(读音 /vjuː/, 类似于view)是一套构建用户界面的渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设...

29390
来自专栏葡萄城控件技术团队

WebStorm 常用功能的使用技巧分享

WebStorm 是 JetBrain 公司开发的一款 JavaScript IDE,使用非常方便,可以使编写代码过程更加流畅。 本文在这里分享一些常用功能的使...

29780
来自专栏葡萄城控件技术团队

Angular的12个经典问题,看看你能答对几个?(文末附带Angular测试)

Angular作为目前最为流行的前端框架,受到了前端开发者的普遍欢迎。不论是初学Angular的新手,还是有一定Angular开发经验的开发者,了解本文中的12...

22180
来自专栏静默虚空的博客

Notepad++ 实用技巧

Notepad++是一款开源的文本编辑器,功能强大。很适合用于编辑、注释代码。它支持绝大部分主流的编程语言。 本文主要列举了本人在实际使用中遇到的一些技巧。  ...

21570
来自专栏编程之旅

PHP开发——yii2多图上传组件的使用

最近在使用yii2开发一个表单页面的时候,有多图上传的需求,稍微找了找这方面的组件,基本都安利fileInput这个组件,于是就尝试着使用这个库来完成后端表单页...

30310
来自专栏有趣的Python和你

人生若只如初见,何必找包爬数据SeleniumPhantomJS豆瓣登陆

13040
来自专栏小尘哥的专栏

thymeleaf中使用layui

头部引入css,尾部引入js,定义两个模板(一个也可以,里面的碎片分开写,我喜欢写两个分别引入),注意th:fragment,fragment即碎片,可以在模板...

97660
来自专栏Google Dart

AngularDart4.0 指南-体系结构概述 顶

AngularDart(我们通常在这个文档中简单地称为Angular)是一个框架,用于在HTML和Dart中构建客户端应用程序。它是作为Angular包发布的,...

9030
来自专栏向治洪

Vue.js简介

Vue.js简介 Vue.js(读音 /vjuː/, 类似于view)是一套构建用户界面的渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设...

32070

扫码关注云+社区

领取腾讯云代金券