码迷,mamicode.com
首页 > Web开发 > 详细

JS 从剪贴板上传图片

时间:2020-05-17 01:31:02      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:username   事件   内容   test   tee   ast   exp   fun   doc   

    用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二进制

请看昨日文章:

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 从剪贴板上传图片

标签:username   事件   内容   test   tee   ast   exp   fun   doc   

原文地址:https://www.cnblogs.com/xiami2046/p/12902930.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!