应用简介:此文主要是描述如何在前端div中直接ctrl+v 粘贴图片,并上传到服务器,包括拖拽图片文件到div中

应用场景描述:用QQ或者其它切图软件截图,在指定的div中ctrl+v 粘贴并显示,点击上传按钮,图片上传到服务器。类似实现了此功能的网站有 知乎 强力建议博客园实现此功能,写博客时插入图片方便的多。

适用环境:本代码目前适用谷歌浏览器、火狐,其它浏览器需要稍微改良一下即可,问题不大。

开发环境:vs2015 mvc

不说废话了,开始吧:

1:首先创建HTML元素,我们要粘贴的图片就是显示在 id=pasteImg 的div里面,注意 需要设置div的 contenteditable="true" 属性才可以编辑哦。

<div id="pasteImg" style="width:400px;height:300px;border:dashed" contenteditable="true"></div>
<button style="width:30px;height:20px;" id="btnGO">上传图片</button>

2:写js代码:绑定粘贴事件 上传图片服务器

 window.onload = function () {

        function paste_img(e) {

            if (e.clipboardData && e.clipboardData.items) {

                var imageContent = e.clipboardData.getData('image/png');
ele = e.clipboardData.items
for (var i = 0; i < ele.length; ++i) {
//粘贴图片
if (ele[i].kind == 'file' && ele[i].type.indexOf('image/') !== -1) {
var blob = ele[i].getAsFile();
window.URL = window.URL || window.webkitURL;
var blobUrl = window.URL.createObjectURL(blob);
// 显示到div中,此时是显示的本地图片数据,并没有上传到服务器
var new_img = document.createElement('img');
new_img.setAttribute('src', blobUrl);
new_img.setAttribute('blobdata', blob);
// 移动div光标到新元素后面
insertHtmlAtCaret(new_img);
// 直接上传,当然你也可以不在这上传,可以点击按钮在上传
  uploadImg(blob);
}
//粘贴文本
else if (ele[i].kind === "string" && ele[i].type.indexOf('text/plain') != -1) {
                        //粘贴文本回调函数
ele[i].getAsString(
                                function (str) {
    insertHtmlAtCaret(document.createTextNode(str));//插入文本到光标处 并移动光标到新位置
}) }
else return; } }
else {
alert('不支持的浏览器');
}
}
//绑定粘贴事件
document.getElementById('pasteImg').onpaste = function () { paste_img(event); return false; };
}

3:下面是insertHtmlAtCaret方法,主要实现在div移动光标的位置,用不上的直接跳过此步骤

//聊天内容框 插入文本或者其他元素后,移动置光标到最新处
function insertHtmlAtCaret(childElement) {
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents(); var el = document.createElement("div");
el.appendChild(childElement);
var frag = document.createDocumentFragment(), node, lastNode;
while ((node = el.firstChild)) {
lastNode = frag.appendChild(node);
} range.insertNode(frag);
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
}
else if (document.selection && document.selection.type != "Control") {
// IE < 9
//document.selection.createRange().pasteHTML(html);
}
}

4:采用XHR上传图片数据

    var createStandardXHR = function () {
try {
return new window.XMLHttpRequest();
} catch (e) {
return false;
}
};
var createActiveXHR = function () {
try {
return new window.ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
return false;
}
}; var xhr; function createXHR() {
var temp = createStandardXHR() || createActiveXHR(); if (window.XDomainRequest === undefined) {
return temp;
} else {
return new XDomainRequest();
}
}
//前端上传方法
function uploadImg(obj) { xhr = createXHR();
if (xhr) {
xhr.onerror = err;
xhr.ontimeout = timeo;
xhr.onprogress = progres;
xhr.onload = loadd;
xhr.timeout = timeo; }
else {
alert("Failed to create");
} //发送的数据
var fd = new FormData();
fd.append("image", obj, "imgtest.png"); //使用ajax发送
xhr.open('POST', '/Home/uploadFun', true);//第二个参数是服务器处理action,各个语言提供方式不一样,我这是.net mvc 后台处理的,具体方法见步骤5
xhr.send(fd);
} function err() {
// alert("XDR onerror");
} function timeo() {
// alert("XDR ontimeout");
} function loadd() {
// alert("上传完成");
// alert("Got: " + xhr.responseText);
} function progres() {
//alert("XDR onprogress");
} function stopdata() {
xhr.abort();
}

5:后台接收图片数据处理方法,本人采用 .net MVC后台,根据自己的语言不通采用对应的处理方式

public class HomeController : Controller
{
public ActionResult Index()
{
return View();
} [HttpPost]
public ActionResult uploadFun()
{
if (Request.Files.Count > )
{
var file = Request.Files[];
if (file != null && file.ContentLength > )
{
//验证文件格式
var extension = Path.GetExtension(file.FileName);
//if (extension != ".xls" && extension != ".xlsx")
//{
//} //上传成功的图片URL
var fileFullPath = Path.Combine(Request.MapPath("~/uploads"), DateTime.Now.ToString("yyyyMMddHHmmss") + Path.GetFileName(file.FileName));
file.SaveAs(fileFullPath);
return Content("上传成功!url:"+fileFullPath , "text/plain");
}
} returnnew JsonResult();
}
}

6:扩展一下,拖拽图片文件到div 直接发送

//以下是拖拽事件
document.addEventListener("dragenter", function (e) {
e.stopPropagation();
e.preventDefault();
}, false);
document.addEventListener("dragleave", function (e) {
e.stopPropagation();
e.preventDefault();
}, false); document.addEventListener("dragover", function (e) {
e.stopPropagation();
e.preventDefault();
}, false);
document.addEventListener("drop", function (e) {
e.stopPropagation();
e.preventDefault(); handleFiles(e.dataTransfer.files); }, false); //拖拽文件处理事件
handleFiles = function (files) {
for (var i = 0; i < files.length; i++) {
var file = files[i]; //如果拖住进来的是图片文件则显示
if (file.type.match(/image*/)) {
$("#pasteImg").focus();
            var blob =file; 
window.URL = window.URL || window.webkitURL;
var blobUrl = window.URL.createObjectURL(blob); // 显示到div中,此时是显示的本地图片数据,并没有上传到服务器
var new_img = document.createElement('img');
new_img.setAttribute('src', blobUrl);
new_img.setAttribute('blobdata', blob);
            // 移动div光标到新元素后面
insertHtmlAtCaret(new_img);
// 直接上传,当然你也可以不在这上传,可以点击按钮在上传
  uploadImg(blob);
} else { continue; } } }

7:至此就实现了ctrl+v 粘贴图片并发送服务器,也具有拖拽图片文件 并发送服务器的功能

发散:可以做文件上传的东西

待解决:IE浏览器和火狐浏览器可以直接粘贴图片及文件,显示的是数据而不是blob格式而已

这是隔日再来写的,以下是火狐浏览器解决方法,已亲测,可行,只不过,火狐不要写粘贴事件,它已自带

document.getElementById('btnGO').onclick = function () {

            var img = $("#pasteImg").find('img').eq(0);
var blob = dataURLtoBlob(img.attr('src'));
//上传方法
uploadImg(blob); }; //**dataURL to blob**
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
} //**blob to dataURL**
function blobToDataURL(blob, callback) {
var a = new FileReader();
a.onload = function (e) { callback(e.target.result); }
a.readAsDataURL(blob);
}

div中粘贴图片并上传服务器 div中拖拽图片文件并上传服务器的更多相关文章

  1. Python 进行 SSH 操作,实现本地与服务器的链接,进行文件的上传和下载

    Python 进行 SSH 操作,实现本地与服务器的链接,进行文件的上传和下载 2018年5月26日 19:03 阅读 375 评论 7 我本地和服务器的连接一直使用的是 Xshell 5,而在与服务 ...

  2. 记crt 在windows与linux服务器之间利用ftp进行文件的上传下载

    我们首先来熟悉一些相关的命令以及操作: ls      #展示linux服务器当前工作目录[你连接sftp时所处的目录]下的所有文件以及文件夹 lcd  F:\niki      #绑定你在windo ...

  3. 文件上传之——用SWF插件实现文件异步上传和头像截取

    之前写过几篇文件上传,那些都不错.今天小编带领大家体会一种新的上传方法,及使用Flash插件实现文件上传. 使用Flash的好处就是可以解决浏览器兼容性问题.之前我写的一个快捷复制功能也是利用的Fla ...

  4. 如何让div中的span垂直居中 ----height:100%设置div的高度

    如果div中只有一个span一个元素,可以使用line-height.如果div中还有其他元素,可以设置span的css如下: .span{ position: absolute; top: 50%; ...

  5. js实现类似微信网页版在可编辑的div中粘贴内容时过滤剪贴板的内容,光标始终在粘贴内容后面,以及将光标定位到最后的方法

    过滤剪贴板内容以及定位可编辑div光标的方法: <!DOCTYPE html><html lang="en"><head>  <meta ...

  6. Spring MVC 上传、下载、显示图片

    目录 1. 准备工作 1.1 数据库表准备 1.2 实体类 User 和 Mapper(DAO) 1.3 pom.xml 依赖包 1.4 SSM 框架的整合配置 2. 控制器 UserControll ...

  7. b/s利用webuploader实现超大文件分片上传、断点续传

    本人在2010年时使用swfupload为核心进行文件的批量上传的解决方案.见文章:WEB版一次选择多个文件进行批量上传(swfupload)的解决方案. 本人在2013年时使用plupload为核心 ...

  8. 前端利用webuploader实现超大文件分片上传、断点续传

    本人在2010年时使用swfupload为核心进行文件的批量上传的解决方案.见文章:WEB版一次选择多个文件进行批量上传(swfupload)的解决方案. 本人在2013年时使用plupload为核心 ...

  9. 使用webuploader组件实现大文件分片上传,断点续传

    本人在2010年时使用swfupload为核心进行文件的批量上传的解决方案.见文章:WEB版一次选择多个文件进行批量上传(swfupload)的解决方案. 本人在2013年时使用plupload为核心 ...

随机推荐

  1. 牛客提高D1t2 最小生成链

    分析 我们发现可以把题目转化为:有一个序列a,问它的排列中相邻两个值异或的最大值的最小值 我们发现序列的构成一定是前几位全是一样的 从某一位开始左面全是0右面全是1 所以只要找到一种方案是的交界两个值 ...

  2. ruby file

    E:/AutoTHCN/lib/report/generate_report/web14/20190516/LoanTool.636936123857869205_190516_140514.xlsx ...

  3. cmath模块——复数域数学函数模块

    cmath——复数域数学函数模块 转自:https://blog.csdn.net/zhtysw/article/category/7511293 该模块属于内置模块,随时可以调用.它提供了数学函数在 ...

  4. Oracle--索引视图序列等对象

    ---恢复内容开始--- 索引 与表类似,不仅需要在DD中保存索引的定义,还需要在表空间为它分配实际的存储空间. 将索引和对应的表分别存放在不同硬盘的不同表空间中能够提高查询的速度,因为Oracle能 ...

  5. 设计模式 - 建造者模式 Builder Pattern

    简介 场景 在创建复杂对象时,用户无须关心该对象所包含的属性以及它们的组装方式,只需要指定复杂对象的类型和内容就可以构建它们. 模式定义 建造者模式:将一个复杂对象的构建与表示分离,使得同样的构建过程 ...

  6. PHP 数组下标自动转换为整型的坑

    在做项目时,上线后遇到一个 BUG,有一个数组存储了下标从 '01'到'18' 总共18组数据.上线前测试了前几组数据,没问题.上线后,在用户选择'15'时报错,找不到这个数据.查了一下代码,数据是没 ...

  7. Xpath表达式的粗介绍

    关于在自动化中Xpath表达式的书写,其实我也只是刚刚入门,粗略的跟着网上的教程学了一下,这篇我就来分享总结一下我学习到的知识. 首先呢,我们先认识一下什么是Xpath.Xpath是XML路径语言,它 ...

  8. 使EasyUI的window、panel、dialog 不被拖出页面

    function easyuiPanelOnMove(left, top) {  var l = left;  var t = top;  if (l < 1) {    l = 1;  }  ...

  9. 20190814 On Java8 第三章 万物皆对象

    第三章 万物皆对象 对象创建 数据存储 有5个不同的地方可以存储数据: 寄存器 (Registers) 最快的存储区域,位于CPU内部 .无法直接控制. 栈内存(Stack) 存在于常规内存 RAM ...

  10. 跨平台自动构建工具v1.0.2 发布

    XMake是一个跨平台自动构建工具,支持在各种主流平台上构建项目,类似cmake.automake.premake,但是更加的方便易用,工程描述语法更简洁直观,支持平台更多,并且集创建.配置.编译.打 ...