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为核心 ...
随机推荐
- python中的变量的学习
今年以来,时间都安排在学习python语言上了.(python3) 从最基础的变量开始学习.尽管以前学习过一段时间,但这次是系统性的学习,所以多花点时间,重新开始.学习完基础知识后,多练习几个项目. ...
- :nth-child 与 ;nth-of-child
//:nth-child:是选择父元素下的第几个元素,不分标签类别,计数从1开始 //:nth-of-type:是选择父元素下的同类型元素的第几个元素.区分标签类别,计数从1开始
- H3C CAS 介绍 & 基本概念
目录 目录 基本概念 H3C CAS 中的虚拟机 虚拟机中的虚拟设备 虚拟 CPU 的 3 种工作模式 虚拟网卡的 3 种类型 虚拟磁盘的三种类型 虚拟机辅助工具 CAS Tools 虚拟机外的虚拟设 ...
- 测开之路六十五:UI测试平台之js
//添加网址的函数,生成一个输入网址的标签,并且把标签append到id为cases下function browser() { var html = '\ <div class="ro ...
- PHP 数组函数-数组排序
php数组排序函数sort ( &$arr [,fruits] ) 对数组进行从低到高排序 ,并赋予新的键名 返回boolrsort ( &$arr [,fruits] ) 对数组进行 ...
- SqlServer 事物
Ø 事务 在数据库中有时候需要把多个步骤的指令当作一个整体来运行,这个整体要么全部成功,要么全部失败,这就需要用到事务. 1. 事务的特点 事务有若干条T-SQL指令组成,并且所有的指令昨晚一个整体提 ...
- 基于docker registry镜像安装私服docker hub
采用docker registry镜像安装docker私服,通过https://hub.docker.com/_/registry链接搜索registry镜像 1.输入命令:docker pull r ...
- Leapin' Lizards [HDU - 2732]【网络流最大流】
题目链接 网络流直接最大流就是了,只是要拆点小心一个点的流超出了原本的正常范围才是. #include <iostream> #include <cstdio> #includ ...
- tensorflow 之Dataset数据集之批量数据
###生成批次数据 import tensorflow as tf '''reapt()生成重复数据集 batch()将数据集按批次组合''' file_name = ['img1','img2',' ...
- mybatis全局配置mybatis-config.xml
大部分时候,我们都是在Spring 里面去集成MyBatis.因为Spring 对MyBatis 的一些操作进行的封装,我们不能直接看到它的本质,所以先看下不使用容器的时候,也就是编程的方式,MyBa ...