欢迎访问琢舟百科

如何截图片 如何截图片水印

频道:星座测试 日期: 浏览:1224

(点击上方公众号,可快速关注)

作者:郑武江(@OAuth_v2)

链接:seejs.me/2016/11/30/paste-snapshot/

作者:郑武江(@OAuth_v2)

链接:seejs.me/2016/11/30/paste-snapshot/

做这个尝试,只为了解决一个问题:如何在网页中读取剪贴板中的图片数据,并在页面中展示或保存到图片服务器。场景可以简单描述为,通过任意屏幕截图工具(QQ、旺旺,PrintScreen键等),截图之后网页中的文本框内粘贴(Ctrl+V、右键等),并在页面中使用图片数据。文字描述比较抽象,我们用一个gif图片来形象的展示一下效果:

ClipboardEvent(剪贴板事件)

ClipboardEvent 接口描述了与修改剪切板相关的事件,这些事件包括 cut 、copy 和 paste 事件。

ClipboardEvent 接口描述了与修改剪切板相关的事件,这些事件包括 cut 、copy 和 paste 事件。

先解决一个问题:为什么要说ClipboardEvent?

首先,无论是截图还是在网页中“复制图片”,最终都是将图片数据存储到了系统剪贴板中。其次,当执行“粘贴”操作的时候是将剪贴板中的数据读出来使用,而读取剪贴板中的图片(文件)数据,更需要直接使用paste事件完成。

第二个问题:为什么要在文本框中“粘贴”,是必须的吗?

展开全文

先从paste事件来说,经测试paste事件可以绑定到任意HTML元素上的,并非必须使用文本框。再来猜测下使用场景,粘贴操作涉及到数据写入问题,内容不可能写入到页面中的只读区域,所以按常理来说,只可能是粘贴到页面中的可写区域。再者,最容易让人想到的场景便是一个聊天会话,因此首先想到的便是文本框控件。

功能实现

功能逻辑比较简单,截图完成或在网页中复制图片后,图片数据就保存到系统剪贴板上了。我们代码中需要实现的就是在paste事件中实现剪贴板中的图像数据读取和处理逻辑。拿到图像数据后,就可以根据自己的业务逻辑进行下一步操作了。代码如下:

(function(){

varsender= document.getElementById('J_MsgSender'),

list= document.getElementById('J_MsgList');

functionpasteImage(imgObj){

varfile= imgObj.getAsFile?imgObj.getAsFile(): imgObj,reader= newFileReader();

// 读取文件后将其显示在网页中

reader.= function(e){

varimg= newImage(),p= document.('p');

img.src= e.target.result;

p.(img);

list.(p);

};

}

sender.addEventListener('paste',function(ev){

// 通过事件对象访问系统剪贴板

如何截图片 如何截图片水印

varev= ev|| window.event,clipboardData= ev.clipboardData,

i= 0,items,item,files;

if(clipboardData){

items= clipboardData.items;

files= clipboardData.files;

if(files&& files.length){

pasteImage(files[0]);

return;

}

if(!items){return;}

for(;i< items.length;i++){

if(items[i].kind=== 'file'&& items[i].type.match(/^image//i)){

item= items[i];

break;

}

}

// 如果存在图片数据

if(item){

pasteImage(item);// 读取该图片

}

}

});

})();

(function(){

varsender= document.getElementById('J_MsgSender'),

list= document.getElementById('J_MsgList');

functionpasteImage(imgObj){

varfile= imgObj.getAsFile?imgObj.getAsFile(): imgObj,reader= newFileReader();

// 读取文件后将其显示在网页中

reader.= function(e){

varimg= newImage(),p= document.('p');

img.src= e.target.result;

p.(img);

list.(p);

};

}

如何截图片 如何截图片水印

sender.addEventListener('paste',function(ev){

// 通过事件对象访问系统剪贴板

varev= ev|| window.event,clipboardData= ev.clipboardData,

i= 0,items,item,files;

if(clipboardData){

items= clipboardData.items;

files= clipboardData.files;

if(files&& files.length){

pasteImage(files[0]);

return;

}

if(!items){return;}

for(;i< items.length;i++){

if(items[i].kind=== 'file'&& items[i].type.match(/^image//i)){

item= items[i];

break;

}

}

// 如果存在图片数据

if(item){

pasteImage(item);// 读取该图片

}

}

});

})();

代码很简单,但有些细节需要注意。在MDN的paste事件说明文档中有说明,数据是存放在事件对象的clipboardData属性中的。而在对clipboardData(DataTransfer类型)的说明中,文件类型的数据应该是被存放在files属性中。这一点在使用拖拽上传等情况时确实是这样的,但是在对截图和复制的网页图片的处理上,各浏览器的实现似乎出现了差异。

在Chrome浏览器中,从剪贴板读取文件时,files属性中并没有内容,而在items属性中却可以找到。而在Firefox中,files属性中存在图片数据,而在items中却找不到文件类型的数据。因此,我不得不在上示代码中做了存在性判断,增加了额外的逻辑。

此外,IE浏览器对剪贴板的处理比较特殊,它将剪贴板数据放在了window作用域下,通过window.clipboardData对剪贴板数据进行操作。但在IE Edge中测试,并未对截图数据进行成功读取,暂不做描述。

其他

如上代码所示,当clipboardData对象中的files属性中没有数据时,我们可以通过遍历items中的元素,并通过元素的kind和type属性判断元素类型,最后通过getAsFile方法将元素转换为文件类型。

其实除了getAsFile方法,还有一个类似的方法,可以将元素转换成字符串,用法示例如下:

item.getAsString(function(str){

console.log(str);

});

item.getAsString(function(str){

console.log(str);

});

该方法可以根据复制源的不同,转换出包含文本格式(比如:字体、字号等)的字符串,如图:

对于文本类型的处理,相信是非常有用的一个方法。

结束语

目前,剪贴板事件还是试验中的功能,在后续的标准文档中可能被修改。我们在实际使用中应该做好兼容处理,附兼容性参考、在线演示。

觉得本文对你有帮助?请分享给更多人

关注「前端大全」,提升前端技能

与本文知识相关的文章:

【处女座男人对待感情的态度】处女座男生的感情观

【为什么很多人想成为水象星座】水象星座都是变态

【星座神婆】星座神婆星座

【为什么摩羯女出轨率高】摩羯女出轨了很可怕

【1月出生的人是什么星座】1月份出生的人是什么星座?

关键词:如何截图片