用Ubuntu两年多了,习惯了Ubuntu的操作感觉比WIN用起来还爽,就一点不爽,生态应用很少,好多WIN上好用的软件在Ubuntu找不到的,希望以后的软件可以做到一次编译全平台通用. 即使用上Wine有的软件应用也存在兼容性问题.比如QQ,Photoshop,微信,旺旺.

所以,在Ubuntu使用过程中,习惯了用web来访问,凡事web-Application通通喜欢.

微信和钉钉经常用,不喜欢wine安装的应用,就直接网页版微信,网页版钉钉,发现好YI功能,当我截图复制到剪贴板后,可以直接Ctrl+V在网页版微信,钉钉粘贴,不用在把图片先保存在电脑上,再选择发送文件这么复杂.

    

然后呢,命题就出来了,如何做到从剪贴板获取图片并发送图片呢?

paste剪贴板事件

onpaste 事件在用户向元素中粘贴文本时触发。

有三种方式可以在元素中粘贴内容:

  • 按下 CTRL + V
  • 从浏览器的编辑菜单中选择 "Paste(粘贴)"
  • 右击鼠标按钮在上下文菜单中选择 "Paste(粘贴)" 命令

参考:https://www.w3cschool.cn/jsref/event-onpaste.html

绑定的元素不一定是input,普通的div也是可以绑定的,如果是给document绑定了,就相当于全局了,任何时候的粘贴操作都会触发。

粘贴事件提供了一个clipboardData的属性,如果该属性有items属性,那么就可以查看items中是否有图片类型的数据了。

clipboardData介绍

介绍一下clipboardData对象,它实际上是一个DataTransfer类型的对象,DataTransfer是拖动产生的一个对象,但实际上粘贴事件也是它。

clipboardData的属性介绍

属性 类型 说明
dropEffect String 默认是 none
effectAllowed String 默认是 uninitialized
files FileList 粘贴操作为空List
items DataTransferItemList 剪切板中的各项数据
types Array 剪切板中的数据类型 该属性在Safari下比较混乱

items介绍

items是一个DataTransferItemList对象,自然里面都是DataTransferItem类型的数据了。

items属性

itemsDataTransferItem有两个属性kindtype

属性 说明
kind 一般为string或者file
type 具体的数据类型,例如具体是哪种类型字符串或者哪种类型的文件,即MIME-Type

items方法

方法 参数 说明
getAsFile 如果kindfile,可以用该方法获取到文件
getAsString 回调函数 如果kindstring,可以用该方法获取到字符串,字符串需要用回调函数得到,回调函数的第一个参数就是剪切板中的字符串
 
在原型上还有一些其他方法,不过在处理剪切板操作的时候一般用不到了。

types介绍

一般types中常见的值有

说明
text/plain 普通字符串
text/html 带有样式的html
Files 文件(例如剪切板中的数据)

以上介绍COPY来自: https://www.jb51.net/article/123071.htm

FileReader对象

FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。其中File对象可以是来自用户在一个<input>元素上选择文件后返回的FileList对象,也可以来自拖放操作生成的 DataTransfer对象,还可以是来自在一个HTMLCanvasElement上执行mozGetAsFile()方法后返回结果。

事件处理

FileReader.onload处理load事件。该事件在读取操作完成时触发。

FileReader.onloadend处理loadend事件。该事件在读取操作结束时(要么成功,要么失败)触发。

方法

FileReader.readAsDataURL()开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容。

readAsDataURL: 该方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成(DONE),并触发 loadend 事件,同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。

示例: https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader/readAsDataURL

function previewFile() {
var preview = document.querySelector('img');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader(); reader.addEventListener("load", function () {
preview.src = reader.result;
}, false); if (file) {
reader.readAsDataURL(file);
}
}

来自:https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader

base64数据转blob二进制

请看昨日文章:

JS 实现blob与base64互转

/**
* base64 to blob二进制
*/
function dataURItoBlob(dataURI) {
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; // mime类型
var byteString = atob(dataURI.split(',')[1]); //base64 解码
var arrayBuffer = new ArrayBuffer(byteString.length); //创建缓冲数组
var intArray = new Uint8Array(arrayBuffer); //创建视图 for (var i = 0; i < byteString.length; i++) {
intArray[i] = byteString.charCodeAt(i);
}
return new Blob([intArray], {type: mimeString});
}

呈上仿制代码

ok,以上需要的事件, FileReader对象操作,base64数据转换都有了,那我们就直接上代码.

ImageClipboard.html

<div id="box"></div>
<script type="text/javascript"> // window.addEventListener('paste', pasteHandler); pasteHandler= fun...
window.addEventListener('paste', function (e) {
var items;
if (e.clipboardData && e.clipboardData.items) {
items = e.clipboardData.items;
if (items) {
items = Array.prototype.filter.call(items, function (element) {
return element.type.indexOf("image") >= 0;
}); Array.prototype.forEach.call(items, function (item) {
var blob = item.getAsFile();
var reader = new FileReader();
reader.onloadend = function (event) {
var imgBase64 = event.target.result; // event.target.result.split(",") [0]=data:image/png;base64 [1]=data
console.log(imgBase64); // base64
var dataURI = imgBase64;
var blob = dataURItoBlob(dataURI); // blob
console.log(blob);
uploadImg(blob); };
reader.readAsDataURL(blob); });
}
}
}); /**
* base64 to blob二进制
*/
function dataURItoBlob(dataURI) {
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; // mime类型
var byteString = atob(dataURI.split(',')[1]); //base64 解码
var arrayBuffer = new ArrayBuffer(byteString.length); //创建缓冲数组
var intArray = new Uint8Array(arrayBuffer); //创建视图 for (var i = 0; i < byteString.length; i++) {
intArray[i] = byteString.charCodeAt(i);
}
return new Blob([intArray], {type: mimeString});
} /**
* 上传图片 FormData
*/
function uploadImg(file) {
var formData = new FormData();
formData.append('my-image-file', file);
formData.append('username', 'myfile'); // 添加自定义数据 var xhr = new XMLHttpRequest();
xhr.open('POST', '/html/upload-ser.php');
xhr.onload = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
var data = JSON.parse(xhr.responseText), tarBox = document.getElementById('box');
if (data.id == 1) {
var img = document.createElement('img');
img.className = 'my_img';
img.src = data.src;
tarBox.appendChild(img); return 'aaa';
} else {
alert(data.msg);
}
} else {
console.log(xhr.statusText);
}
}
};
xhr.onerror = function (e) {
console.log(xhr.statusText);
}
xhr.send(formData);
}
</script>

服务端upload-ser.php

<?php

//print_r($_POST);
//print_r($_FILES); $file = $_FILES['my-image-file'];
if ($file['error'] == 0) {
define('ROOT', __DIR__);
if (is_uploaded_file($file['tmp_name'])) {
$ext = explode('/', $file['type'])[1];
$filename = "{$file['name']}_" . date("ymdHis") . ".{$ext}";
$mu = move_uploaded_file($file["tmp_name"], ROOT . "/upload/" . $filename);
if ($mu) {
exit(json_encode(['id' => 1, 'src' => 'upload/' . $filename]));
} else {
exit(json_encode(['id' => 2, 'msg' => 'move file fail']));
}
} else {
exit(json_encode(['id' => 2, 'msg' => 'failed no post']));
}
} else {
exit(json_encode(['id' => 2, 'msg' => $file['error']]));
}

在页面中,我们直接Ctrl+V后, 可以先通过打印POST和FILES看下数据

username 是自定义的post数据,my-image-file是file数据.

console.log打印:

通过xhr返回callback得到上传后的信息

查看上传的目录

GIF

JS 从剪贴板上传图片的更多相关文章

  1. ajaxFileUpload.js 无刷新上传图片,支持多个参数同时上传,支持 ie6-ie10

    /* 131108-xxj-ajaxFileUpload.js 无刷新上传图片 jquery 插件,支持 ie6-ie10 依赖:jquery-1.6.1.min.js 主方法:ajaxFileUpl ...

  2. 为什么不能用 JS 获取剪贴板上的内容?

    为什么不能用 JS 获取剪贴板上的内容? 为什么不能用 JS 获取剪贴板上的内容? 发一串口令给朋友朋友复制这串口令,然后访问你的网站你在网站上用 JS 读取朋友剪贴板上的口令根据不同的口令,显示不同 ...

  3. JS获取剪贴板图片之后的格式选择与压缩问题

    前言 某年某月的某一天,突然发现博客服务器上上传的图片都比较大,一些很小的截图都有几百kb,本来服务器带宽就慢,不优化一下说不过去. 问题细述 特别说明:本文代码因为只是用于我自己后台写markdow ...

  4. 原生js复制粘贴上传图片前后台代码,兼容firebox,chrome, ie11,亲测有效

    需求:粘贴上传图片,截图工具,右键粘贴,或者ctrl+v粘贴 方法1:可直接套用富文本框的图片上传功能,完成复制粘贴 缺点:麻烦,样式难控制 方法2:用原生js完成,以下案例基于此,样式请自己动手调整 ...

  5. js无刷新上传图片,服务端有生成缩略图,剪切图片,iphone图片旋转判断功能

    html: <form action="<{:AppLink('circle/uploadimg')}>" id="imageform" me ...

  6. js php xmlrequest 上传图片

    本来想用插件上传图片的,后来自己写了一个简单的js实现异步的图片上传,不多说上代码很easy upload.php <?php if(isset($_FILES["myfile&quo ...

  7. Asp.Net MVC 中JS通过ajaxfileupload上传图片获取身份证姓名、生日、家庭住址等详细信息

    客户要求用身份证图片上传获取身份证的详细信息就下来研究了一下(现在的客户真的懒 身份证信息都懒得输入了哈哈...),经过慢慢研究,果然皇天不负有心人搞出来了.这个借助的是腾讯的一个SKD  腾讯优图云 ...

  8. js前台检测上传图片大小的总结

    最近一直在做上传图片的前端检测,不通过后台就完成这个动作.但实际是,实际效果差强人意. html5的fileApi出来后,对文件的处理才变得方便了些,对它的简单介绍可以看我的前面的博客.现在支持的浏览 ...

  9. js预览上传图片

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

随机推荐

  1. MySQL单表查询

    MySQL之单表查询 创建表 # 创建表 mysql> create table company.employee5( id int primary key AUTO_INCREMENT not ...

  2. [SDOI2017]遗忘的集合

    [SDOI2017]遗忘的集合 综合了很多套路的题 一看就是完全背包 生成函数! 转化为连乘积形式 Pi....=F 求Ln! 降次才可以解方程 发现方程是: f[i]=∑t|i : bool(t)* ...

  3. 微信小程序之:wepy(二)

    一大堆实例:人家的博客园 代码规范: 1.尽量使用驼峰命名,避免使用$开头,框架内建属性都已$开头,可以使用this直接调用. 2.入口文件.页面.组件后缀都为.wpy. 3.使用ES6语法开发. 4 ...

  4. 构建一个maven聚合类型的横向可扩展项目

    那个时候初入java这个大家庭,学习的方向很乱.毕业后,在公司磨练了一年,总想着是该交一份答卷了,可能成绩不会很好,但求及格!那么考试题目呢,我计划搭建一个横向可扩展的项目,可以在平台自扩展各种子项目 ...

  5. EL表达式+JSTL

    一. EL表达式 1.1 什么是EL EL是JSP表达式语言,全称是Expression Language,提供了JSP中简化表达式的方法. 1.2 如何学习EL 没有EL的时候 怎么写 用EL表达式 ...

  6. 分析web.xml

    <?xml version="1.0" encoding="UTF-8"?>  //xml的版本:1.0 和 编码:utf-8 <web-ap ...

  7. 带@的css语法,你知道多少?

    前言 css的顶层样式表由两种规则组成的规则列表构成,一种称为at—rule规则,也就是at规则,另一种是qualified rule,也就是普通规则.今天就学习一下at规则 正文 @charset ...

  8. Python+Selenium+Unittest框架使用——Selenium——定位元素(二)

    1.定位元素(id.name.class.link.partial link) (1)find_element_by_id() 用百度定位测试,用firebug查看定位元素 ,输入框的id为“kw”, ...

  9. django中的分页标签

    class Pagination: def __init__(self, page, page_total, per_one_page=15, max_page=11): ''' :param pag ...

  10. python+redis+kairosdb+cassandra+mysql环境搭建

    环境搭建: python安装: redis安装: 下载.解压.安装 1.wget http://download.redis.io/releases/redis-5.0.0.tar.gz 2.tar ...