div中粘贴图片并上传服务器 div中拖拽图片文件并上传服务器
应用简介:此文主要是描述如何在前端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中拖拽图片文件并上传服务器的更多相关文章
- Python 进行 SSH 操作,实现本地与服务器的链接,进行文件的上传和下载
Python 进行 SSH 操作,实现本地与服务器的链接,进行文件的上传和下载 2018年5月26日 19:03 阅读 375 评论 7 我本地和服务器的连接一直使用的是 Xshell 5,而在与服务 ...
- 记crt 在windows与linux服务器之间利用ftp进行文件的上传下载
我们首先来熟悉一些相关的命令以及操作: ls #展示linux服务器当前工作目录[你连接sftp时所处的目录]下的所有文件以及文件夹 lcd F:\niki #绑定你在windo ...
- 文件上传之——用SWF插件实现文件异步上传和头像截取
之前写过几篇文件上传,那些都不错.今天小编带领大家体会一种新的上传方法,及使用Flash插件实现文件上传. 使用Flash的好处就是可以解决浏览器兼容性问题.之前我写的一个快捷复制功能也是利用的Fla ...
- 如何让div中的span垂直居中 ----height:100%设置div的高度
如果div中只有一个span一个元素,可以使用line-height.如果div中还有其他元素,可以设置span的css如下: .span{ position: absolute; top: 50%; ...
- js实现类似微信网页版在可编辑的div中粘贴内容时过滤剪贴板的内容,光标始终在粘贴内容后面,以及将光标定位到最后的方法
过滤剪贴板内容以及定位可编辑div光标的方法: <!DOCTYPE html><html lang="en"><head> <meta ...
- Spring MVC 上传、下载、显示图片
目录 1. 准备工作 1.1 数据库表准备 1.2 实体类 User 和 Mapper(DAO) 1.3 pom.xml 依赖包 1.4 SSM 框架的整合配置 2. 控制器 UserControll ...
- b/s利用webuploader实现超大文件分片上传、断点续传
本人在2010年时使用swfupload为核心进行文件的批量上传的解决方案.见文章:WEB版一次选择多个文件进行批量上传(swfupload)的解决方案. 本人在2013年时使用plupload为核心 ...
- 前端利用webuploader实现超大文件分片上传、断点续传
本人在2010年时使用swfupload为核心进行文件的批量上传的解决方案.见文章:WEB版一次选择多个文件进行批量上传(swfupload)的解决方案. 本人在2013年时使用plupload为核心 ...
- 使用webuploader组件实现大文件分片上传,断点续传
本人在2010年时使用swfupload为核心进行文件的批量上传的解决方案.见文章:WEB版一次选择多个文件进行批量上传(swfupload)的解决方案. 本人在2013年时使用plupload为核心 ...
随机推荐
- HDU 4321 Arcane Numbers 2
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4321 ----------------------------------------------- ...
- 【CDN+】 Kylin 的初步认识与理解
前言 项目中用到了Kylin框架来处理数据,那么作为项目成员需要了解哪些关于Kylin的知识呢,本文就Kylin得基本概念和原理进行简述. Kylin基本概念 首先想到的学习路径是Kylin官网: h ...
- leetcode 20. 有效的括号 (python)
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合.左括号必须以正确的顺序闭合.注意空字符串可被认为是 ...
- Java常用工具——java字符串
一.String常用字符串 package com.imooc.string; public class StringDemo { public static void main(String[] a ...
- Oracle_管理控制文件和日志文件
控制文件: 控制文件在数据库创建时被自动创建,并在数据库发生物理变化时更新.控制文件被不断更新,并且在任何时候都要保证控制文件是可用的.只有Oracle进程才能安全地更新控制文件的内容,所以,任何时候 ...
- (转)Linux下编译安装log4cxx
Linux下编译安装log4cxx 一个项目的服务器端在Linux平台下,用到了开源日志库log4cxx,这个库是apache项目的一个子库.功能很不错.下面记录下它的编译和安装过程. log4cxx ...
- python面试题之Python如何实现单例模式?
#使用__metaclass__(元类)的高级python用法 class Singleton2(type): def __init__(cls, name, bases, dict): super( ...
- Codeforces - 1191E - Tokitsukaze and Duel - 博弈论 - 尺取
https://codeforc.es/contest/1191/problem/E 参考自:http://www.mamicode.com/info-detail-2726030.html 和官方题 ...
- JavaScript中的柯里化
转载自:https://www.cnblogs.com/zztt/p/4142891.html 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Ha ...
- 关于在IE下JavaScript的 Stack overflow at line 错误可能的原因
该错误只在IE中出现,出现该提示的原因主要有两种: 1. 重定义了系统的触发事件名称作为自定义函数名如: onclick / onsubmit … 都是系统保留的事件名称,不允许作为重定义函数名称 ...