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为核心 ...
随机推荐
- ora4031
http://blog.itpub.net/23135684/viewspace-1203447/ Mon Sep 11 08:56:10 2017Errors in file /oracle/db/ ...
- p5414 [YNOI2019]排序
分析 这是真正的云南oi/px 我们需要考虑保留一段不降子序列 剩余的自由往前往后移动 所以dp一下即可 代码 #include<bits/stdc++.h> using namespac ...
- Jenkins 官网文档翻译汇总
Jenkins 官网地址 Jenkins 官网文档地址 用户手册 安装 Jenkins 使用 Jenkins 使用凭证 Pipeline 流水线 开始使用 Pipeline 使用 Jenkinsfil ...
- Linux系统的镜像文件iso下载地址
CentOS-6.1-x86_64-bin-DVD1.iso 官方网址:http://archive.kernel.org/centos-vault/6.1/isos/x86_64/ 下载链接地址:h ...
- FireFox浏览器导出文件名乱码
解决方案1 String codedFileName = "导出文件名.xls"; String agent = request.getHeader("USER-AGEN ...
- go 文件读写
go 文件读写有很多方式 ioutil读文件 package main import ( "io/ioutil" "fmt" ) func main() { d ...
- topic模式下的收发
生产者: import pika import sys connection = pika.BlockingConnection(pika.ConnectionParameters( host='lo ...
- 【学习总结】cpu缓存
参考链接: cpu缓存java性能问题初探 高速缓存 在内存与cpu寄存器之间,还有一块区域叫做cpu高速缓存,即我们常常说的cache. cache分为L1.L2.L3三级缓存,速度递减,离cpu越 ...
- ROT13加密和解密
问题 ROT13(回转13位)是一种简易的替换式密码算法.它是一种在英文网络论坛用作隐藏八卦.妙句.谜题解答以及某些脏话的工具,目的是逃过版主或管理员的匆匆一瞥.ROT13 也是过去在古罗马开发的凯撒 ...
- A星寻路
逻辑代码 using System.Collections.Generic; using System.Text; using UnityEngine; namespace Game { public ...