博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS实现将图片复制到剪贴板
阅读量:5797 次
发布时间:2019-06-18

本文共 3378 字,大约阅读时间需要 11 分钟。

前言

最近项目新增需求:用户能够拖拽页面上的图片文件到word文档。

当操作浏览器里拖拽图片至别的程序,在word文档中展示出获取到的只是图片的url地址,而非预期的图片文件。在现有的拖拽事件所提供api无法满足需求的情况下,换一个思路走:尝试将图片复制到剪贴板

对于原生js的复制操作,已有封装好的库clipboard.js,但是封装得太死,无法满足更多定制化的需求,主要表现在以下两点:

  1. 只接受click事件,无法绑定其他事件。
  2. 只复制目标节点的子节点,对于img标签,如果不额外包裹一层父元素,无法实现图片复制。

参考clipboard.js源码,了解了实现原理后(其实非常简单!:) ),我们就能自己动手封装一个复制方法:

概述

Range对象

表示包含节点和部分文本节点的文档片段。最常见的就是用户在浏览器拖动鼠标选择的内容(user selection)

clipboard.png

比如上图这块蓝色高亮区域。

在现代浏览器中(IE9以上),你可以通过Document.createRange()方法或者new Range()创建一个Range对象;当需要获取user selection时,你应该使用window.getSelection()方法获取对象

有点懵?

clipboard.png

刚了解了Range对象,而Selection对象又是什么?阅读了之后,还是疑惑?

clipboard.png

Selection对象表示用户的选择,而Range对象则表示文档的连续部分,与任何视觉表示无关。一个Selection对象几乎可由0到多个Range表示出来,当然,Range对象也能独立于Selection而被完全的创建和修改。

简单的演示代码

html部分:

这是一段文字 AAAAAAAAAA BBBBBBBBBB Range

js部分:

var btn1 = document.getElementById('button1'),    btn2 = document.getElementById('button2'),    input = document.getElementById('input'),    rangespan = document.getElementById('range');    var selection = window.getSelection(),    range = document.createRange();btn1.addEventListener("click", function(event) {    input.value = selection.toString();}); btn2.addEventListener("click", function(event) {    range.selectNode(rangespan);    selection.removeAllRanges(); //删除包含在selection原本的range,也就是取消用户选中的范围    selection.addRange(range); //让选中部分变成我们自己定义的节点内容});

一点就会 :)

兼容陈旧IE版本

Microsoft提供了类似的接口。

在实际代码部分会展示Microsoft TextRange的基本使用。

execCommand方法

方法允许运行命令来操纵可编辑区域的内容。该方法的第一个参数是命令的名称,参数类型为DOMString。

在这里,我们将利用execCommand方法的copy命令实现复制选中的内容:

document.execCommand('copy')

execCommand API起源于IE,后来被添加到HTML5(),在。更多请查看。

我们回到前面的演示代码,将btn1的点击事件替换成execCommand命令:

btn1.addEventListener("click", function(event) {    //input.value = selection.toString();    document.execCommand('copy');});

拖动鼠标选择文字,点击按钮后看看能粘贴出什么:)

复制图片功能的具体实现

封装可以兼容ie的getSelect方法

还记得前面的例子里,我们通过rangeselectNode(node)方法获取节点, 再使用selectionremoveAllRanges()方法和addRange(range)将节点替换我们获取的节点。在这里,我们同样可以这样选中我们目标的img节点:

const getSelect = targetNode => {  if (window.getSelection) {    //chrome等主流浏览器    var selection = window.getSelection();    var range = document.createRange();    range.selectNode(targetNode);    selection.removeAllRanges();    selection.addRange(range);  } else if (document.body.createTextRange) {    //ie    var range = document.body.createTextRange();    range.moveToElementText(targetNode);    range.select();  }}

派发事件

为了不浪费性能,我们使用事件委托到希望被复制的节点上。这里对传入的nodeName进行处理,方便自由的控制被复制一个或多个节点类型。默认为<img>。

const clipboardHandler = (nodeName, event) => {  event = event || nodeName; //不传参时  const type = Object.prototype.toString.call(nodeName).replace(/\[object\s|\]/g, '');  const target = event.target || event.srcElement;  var result = false;  switch (type) {    case 'String':      result = (target.nodeName.toLowerCase() === nodeName);      break;    case 'Array':      result = nodeName.some(item => target.nodeName.toLowerCase() === item);      break;    case 'Object':      nodeName = null;    default:      result = (target.nodeName === 'IMG');  }  if (result) {    //调用之前封装好的getSelect方法    getSelect(target);    document.execCommand('copy');  }}

调用:

[element].addEventListener('mousedown', clipboardHandler); //预备拖动图片按下鼠标时执行复制

传递参数(字符串或数组):

var [somename]Handler = clipboardHandler.bind(null, [nodeName]);[element].addEventListener([eventType],[somename]Handler);

已验证在chrome和ie8上可行(ie8需要对es6语法与bind和addEventListener方法进行pollyfill)

希望能够帮助到你:)

转载地址:http://bpsfx.baihongyu.com/

你可能感兴趣的文章
《Programming WPF》翻译 第5章 1.不使用样式
查看>>
.NET垃圾回收:非托管资源,IDispose和析构函数的结合
查看>>
H2内存数据库 支持存储到文件
查看>>
css3处理sprite背景图压缩来解决H5网页在手机浏览器下图标模糊的问题
查看>>
BlockCanary 一个轻量的,非侵入式的性能监控组件(阿里)
查看>>
【HDU 1228】A + B
查看>>
CentOS 7搭建SVN服务器
查看>>
Atitit.远程接口 监控与木马 常用的api 标准化v2 q216
查看>>
闭包实现循环事件添加
查看>>
linux创建文件树,孩子兄弟树(或广义表),创建文件树及其訪问
查看>>
Floyd最短路算法
查看>>
【荐】如何正确理解PHP之include,include_once,require,require_once等包含作用域
查看>>
Class.forName(String name)方法,到底会触发那个类加载器进行类加载行为?
查看>>
CentOS 6.6 FTP install
查看>>
C#------判断btye[]是否为空
查看>>
图解Ajax工作原理
查看>>
oracle导入导出小记
查看>>
聊一聊log4j2配置文件log4j2.xml
查看>>
NeHe OpenGL教程 第七课:光照和键盘
查看>>
修改上一篇文章的node.js代码,支持默认页及支持中文
查看>>