webuploader 多图片上传
WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。
具体接口参考 webuploader接口文档地址
一、图片上传功能
引入资源
<!--引入CSS-->
<link rel="stylesheet" type="text/css" href="webuploader/webuploader.css"> <!--引入JS-->
<script type="text/javascript" src="webuploader/webuploader.js"></script>
html
<div id="uploader" class="wu-example">
<div class="queueList">
<div id="dndArea" class="placeholder">
<div id="filePicker"></div>
<p>或将照片拖到这里,单次最多可选300张</p>
</div>
</div>
<div class="statusBar" style="display:none;">
<div class="progress">
<span class="text">0%</span>
<span class="percentage"></span>
</div>
<div class="info"></div>
<div class="btns">
<div id="filePicker2"></div>
<div class="uploadBtn">开始上传</div>
</div>
</div>
</div>
css样式
#container {
color: #838383;
font-size: 12px;
} #uploader .queueList {
margin: 20px;
border: 3px dashed #e6e6e6;
}
#uploader .queueList.filled {
padding: 17px;
margin: 0;
border: 3px dashed transparent;
}
#uploader .queueList.webuploader-dnd-over {
border: 3px dashed #999999;
} #uploader p {margin: 0;} .element-invisible {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px,1px,1px,1px);
} #uploader .placeholder {
min-height: 350px;
padding-top: 178px;
text-align: center;
background: url(../../../img/webuploader.png) center 93px no-repeat;
color: #cccccc;
font-size: 18px;
position: relative;
} #uploader .placeholder .webuploader-pick {
font-size: 18px;
background: #00b7ee;
border-radius: 3px;
line-height: 44px;
padding: 0 30px;
*width: 120px;
color: #fff;
display: inline-block;
margin: 0 auto 20px auto;
cursor: pointer;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
} #uploader .placeholder .webuploader-pick-hover {
background: #00a2d4;
} #uploader .placeholder .flashTip {
color: #666666;
font-size: 12px;
position: absolute;
width: 100%;
text-align: center;
bottom: 20px;
}
#uploader .placeholder .flashTip a {
color: #0785d1;
text-decoration: none;
}
#uploader .placeholder .flashTip a:hover {
text-decoration: underline;
} #uploader .filelist {
list-style: none;
margin: 0;
padding: 0;
} #uploader .filelist:after {
content: '';
display: block;
width: 0;
height: 0;
overflow: hidden;
clear: both;
} #uploader .filelist li {
width: 110px;
height: 110px;
background: url(../../img/bg.png) no-repeat;
text-align: center;
margin: 0 8px 20px 0;
position: relative;
display: inline;
float: left;
overflow: hidden;
font-size: 12px;
} #uploader .filelist li p.log {
position: relative;
top: -45px;
} #uploader .filelist li p.title {
position: absolute;
top: 0;
left: 0;
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow : ellipsis;
top: 5px;
text-indent: 5px;
text-align: left;
} #uploader .filelist li p.progress {
position: absolute;
width: 100%;
bottom: 0;
left: 0;
height: 8px;
overflow: hidden;
z-index: 50;
margin: 0;
border-radius: 0;
background: none;
-webkit-box-shadow: 0 0 0;
}
#uploader .filelist li p.progress span {
display: none;
overflow: hidden;
width: 0;
height: 100%;
background: #1483d8 url(../../img/progress.png) repeat-x; -webit-transition: width 200ms linear;
-moz-transition: width 200ms linear;
-o-transition: width 200ms linear;
-ms-transition: width 200ms linear;
transition: width 200ms linear; -webkit-animation: progressmove 2s linear infinite;
-moz-animation: progressmove 2s linear infinite;
-o-animation: progressmove 2s linear infinite;
-ms-animation: progressmove 2s linear infinite;
animation: progressmove 2s linear infinite; -webkit-transform: translateZ(0);
} @-webkit-keyframes progressmove {
0% {
background-position: 0 0;
}
100% {
background-position: 17px 0;
}
}
@-moz-keyframes progressmove {
0% {
background-position: 0 0;
}
100% {
background-position: 17px 0;
}
}
@keyframes progressmove {
0% {
background-position: 0 0;
}
100% {
background-position: 17px 0;
}
} #uploader .filelist li p.imgWrap {
position: relative;
z-index: 2;
line-height: 110px;
vertical-align: middle;
overflow: hidden;
width: 110px;
height: 110px; -webkit-transform-origin: 50% 50%;
-moz-transform-origin: 50% 50%;
-o-transform-origin: 50% 50%;
-ms-transform-origin: 50% 50%;
transform-origin: 50% 50%; -webit-transition: 200ms ease-out;
-moz-transition: 200ms ease-out;
-o-transition: 200ms ease-out;
-ms-transition: 200ms ease-out;
transition: 200ms ease-out;
} #uploader .filelist li img {
width: 100%;
} #uploader .filelist li p.error {
background: #f43838;
color: #fff;
position: absolute;
bottom: 0;
left: 0;
height: 28px;
line-height: 28px;
width: 100%;
z-index: 100;
} #uploader .filelist li .success {
display: block;
position: absolute;
left: 0;
bottom: 0;
height: 40px;
width: 100%;
z-index: 200;
background: url(../../img/success.png) no-repeat right bottom;
} #uploader .filelist div.file-panel {
position: absolute;
height: 0;
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#80000000', endColorstr='#80000000')\0;
background: rgba( 0, 0, 0, 0.5 );
width: 100%;
top: 0;
left: 0;
overflow: hidden;
z-index: 300;
} #uploader .filelist div.file-panel span {
width: 24px;
height: 24px;
display: inline;
float: right;
text-indent: -9999px;
overflow: hidden;
background: url(../../img/icons.png) no-repeat;
margin: 5px 1px 1px;
cursor: pointer;
} #uploader .filelist div.file-panel span.rotateLeft {
background-position: 0 -24px;
}
#uploader .filelist div.file-panel span.rotateLeft:hover {
background-position: 0 0;
} #uploader .filelist div.file-panel span.rotateRight {
background-position: -24px -24px;
}
#uploader .filelist div.file-panel span.rotateRight:hover {
background-position: -24px 0;
} #uploader .filelist div.file-panel span.cancel {
background-position: -48px -24px;
}
#uploader .filelist div.file-panel span.cancel:hover {
background-position: -48px 0;
} #uploader .statusBar {
height: 63px;
border-top: 1px solid #dadada;
padding: 0 20px;
line-height: 63px;
vertical-align: middle;
position: relative;
} #uploader .statusBar .progress {
border: 1px solid #1483d8;
width: 198px;
background: #fff;
height: 18px;
position: relative;
display: inline-block;
text-align: center;
line-height: 20px;
color: #6dbfff;
position: relative;
margin: 0 10px 0 0;
}
#uploader .statusBar .progress span.percentage {
width: 0;
height: 100%;
left: 0;
top: 0;
background: #1483d8;
position: absolute;
}
#uploader .statusBar .progress span.text {
position: relative;
z-index: 10;
} #uploader .statusBar .info {
display: inline-block;
font-size: 14px;
color: #666666;
} #uploader .statusBar .btns {
position: absolute;
top: 10px;
right: 20px;
line-height: 40px;
} #filePicker2 {
display: inline-block;
float: left;
} #uploader .statusBar .btns .webuploader-pick,
#uploader .statusBar .btns .uploadBtn,
#uploader .statusBar .btns .uploadBtn.state-uploading,
#uploader .statusBar .btns .uploadBtn.state-paused {
background: #ffffff;
border: 1px solid #cfcfcf;
color: #565656;
padding: 0 18px;
display: inline-block;
border-radius: 3px;
margin-left: 10px;
cursor: pointer;
font-size: 14px;
float: left;
}
#uploader .statusBar .btns .webuploader-pick-hover,
#uploader .statusBar .btns .uploadBtn:hover,
#uploader .statusBar .btns .uploadBtn.state-uploading:hover,
#uploader .statusBar .btns .uploadBtn.state-paused:hover {
background: #f0f0f0;
} #uploader .statusBar .btns .uploadBtn {
background: #00b7ee;
color: #fff;
border-color: transparent;
}
#uploader .statusBar .btns .uploadBtn:hover {
background: #00a2d4;
} #uploader .statusBar .btns .uploadBtn.disabled {
pointer-events: none;
opacity: 0.6;
}
webuploader.uploader.css
用于保存swf文件 的html 文件
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /theme/hplus/js/plugins/webuploader/
on this server.</p>
<hr>
<address>Apache Server at www.zi-han.net Port 80</address>
</body></html>
webuploader/index.html
上js代码
var BASE_URL = 'js/plugins/webuploader/index.html'; //保存swf文件
jQuery(function() {
function e(e) {
var a = o('<li id="' + e.id + '"><p class="title">' + e.name + '</p><p class="imgWrap"></p><p class="progress"><span></span></p></li>'),
s = o('<div class="file-panel"><span class="cancel">删除</span><span class="rotateRight">向右旋转</span><span class="rotateLeft">向左旋转</span></div>').appendTo(a),
i = a.find("p.progress span"),
t = a.find("p.imgWrap"),
r = o('<p class="error"></p>'),
d = function(e) {
switch (e) {
case "exceed_size":
text = "文件大小超出";
break;
case "interrupt":
text = "上传暂停";
break;
default:
text = "上传失败,请重试"
}
r.text(text).appendTo(a)
};
"invalid" === e.getStatus() ? d(e.statusText) : (t.text("预览中"), n.makeThumb(e,
function(e, a) {
if (e) return void t.text("不能预览");
var s = o('<img src="' + a + '">');
t.empty().append(s)
},
v, b), w[e.id] = [e.size, 0], e.rotation = 0),
e.on("statuschange",
function(t, n) {
"progress" === n ? i.hide().width(0) : "queued" === n && (a.off("mouseenter mouseleave"), s.remove()),
"error" === t || "invalid" === t ? (console.log(e.statusText), d(e.statusText), w[e.id][1] = 1) : "interrupt" === t ? d("interrupt") : "queued" === t ? w[e.id][1] = 0 : "progress" === t ? (r.remove(), i.css("display", "block")) : "complete" === t && a.append('<span class="success"></span>'),
a.removeClass("state-" + n).addClass("state-" + t)
}),
a.on("mouseenter",
function() {
s.stop().animate({
height: 30
})
}),
a.on("mouseleave",
function() {
s.stop().animate({
height: 0
})
}),
s.on("click", "span",
function() {
var a, s = o(this).index();
switch (s) {
case 0:
return void n.removeFile(e);
case 1:
e.rotation += 90;
break;
case 2:
e.rotation -= 90
}
x ? (a = "rotate(" + e.rotation + "deg)", t.css({
"-webkit-transform": a,
"-mos-transform": a,
"-o-transform": a,
transform: a
})) : t.css("filter", "progid:DXImageTransform.Microsoft.BasicImage(rotation=" + ~~ (e.rotation / 90 % 4 + 4) % 4 + ")")
}),
a.appendTo(l)
}
function a(e) {
var a = o("#" + e.id);
delete w[e.id],
s(),
a.off().find(".file-panel").off().end().remove()
}
function s() {
var e, a = 0,
s = 0,
t = f.children();
o.each(w,
function(e, i) {
s += i[0],
a += i[0] * i[1]
}),
e = s ? a / s: 0,
t.eq(0).text(Math.round(100 * e) + "%"),
t.eq(1).css("width", Math.round(100 * e) + "%"),
i()
}
function i() {
var e, a = "";
"ready" === k ? a = "选中" + m + "张图片,共" + WebUploader.formatSize(h) + "。": "confirm" === k ? (e = n.getStats(), e.uploadFailNum && (a = "已成功上传" + e.successNum + "张照片至XX相册," + e.uploadFailNum + '张照片上传失败,<a class="retry" href="#">重新上传</a>失败图片或<a class="ignore" href="#">忽略</a>')) : (e = n.getStats(), a = "共" + m + "张(" + WebUploader.formatSize(h) + "),已上传" + e.successNum + "张", e.uploadFailNum && (a += ",失败" + e.uploadFailNum + "张")),
p.html(a)
}
function t(e) {
var a;
if (e !== k) {
switch (c.removeClass("state-" + k), c.addClass("state-" + e), k = e) {
case "pedding":
u.removeClass("element-invisible"),
l.parent().removeClass("filled"),
l.hide(),
d.addClass("element-invisible"),
n.refresh();
break;
case "ready":
u.addClass("element-invisible"),
o("#filePicker2").removeClass("element-invisible"),
l.parent().addClass("filled"),
l.show(),
d.removeClass("element-invisible"),
n.refresh();
break;
case "uploading":
o("#filePicker2").addClass("element-invisible"),
f.show(),
c.text("暂停上传");
break;
case "paused":
f.show(),
c.text("继续上传");
break;
case "confirm":
if (f.hide(), c.text("开始上传").addClass("disabled"), a = n.getStats(), a.successNum && !a.uploadFailNum) return void t("finish");
break;
case "finish":
a = n.getStats(),
a.successNum ? alert("上传成功") : (k = "done", location.reload())
}
i()
}
}
var n, o = jQuery,
r = o("#uploader"),
l = o('<ul class="filelist"></ul>').appendTo(r.find(".queueList")),
d = r.find(".statusBar"),
p = d.find(".info"),
c = r.find(".uploadBtn"),
u = r.find(".placeholder"),
f = d.find(".progress").hide(),
m = 0,
h = 0,
g = window.devicePixelRatio || 1,
v = 110 * g,
b = 110 * g,
k = "pedding",
w = {},
x = function() {
var e = document.createElement("p").style,
a = "transition" in e || "WebkitTransition" in e || "MozTransition" in e || "msTransition" in e || "OTransition" in e;
return e = null,
a
} ();
if (!WebUploader.Uploader.support()) throw alert("不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器"),
new Error("不支持您的浏览器");
n = WebUploader.create({
pick: {
id: "#filePicker",
label: "点击选择图片"
},
dnd: "#uploader .queueList",
paste: document.body,
accept: {
title: "Images",
extensions: "gif,jpg,jpeg,bmp,png",
mimeTypes: "image/*"
},
swf: BASE_URL + "/Uploader.swf",
disableGlobalDnd: !0,
chunked: !0,
server: "webuploader_photo.html",
duplicate: true,
fileNumLimit: 9,
fileSizeLimit: 5242880,
fileSingleSizeLimit: 1048576,
headers: {
"X-CSRFToken": $.cookie('csrftoken')
}, }),
n.addButton({
id: "#filePicker2",
label: "继续添加"
}),
n.onUploadProgress = function(e, a) {
var i = o("#" + e.id),
t = i.find(".progress span");
t.css("width", 100 * a + "%"),
w[e.id][1] = a,
s()
},
n.on('uploadSuccess', function (file, response) {
var res=JSON.parse(response._raw); //这里可以得到后台返回的数据
// $('#' + file.id).addClass('upload-state-done');
var input = document.createElement("input");
console.log(res.data)
var data = res.data
input.type="hidden";
input.name=data.id;
input.value=data.path;
$("#"+data.id).append(input);
console.log($("#"+data.id))
});
n.onFileQueued = function(a) {
m++,
h += a.size,
1 === m && (u.addClass("element-invisible"), d.show()),
e(a),
t("ready"),
s()
},
n.onFileDequeued = function(e) {
m--,
h -= e.size,
m || t("pedding"),
a(e),
s()
},
n.on("all",
function(e) {
switch (e) {
case "uploadFinished":
t("confirm");
break;
case "startUpload":
t("uploading");
break;
case "stopUpload":
t("paused")
}
}),
n.onError=function(e){
// alert("Error: "+e)
switch (e) {
case 'Q_EXCEED_NUM_LIMIT':
alert("错误:最多上传九张图片!");
break;
case 'Q_EXCEED_SIZE_LIMIT':
alert.msg("错误:文件总大小超出限制!");
break;
case 'F_EXCEED_SIZE':
alert.msg("错误:文件大小超出限制!");
break;
case 'Q_TYPE_DENIED':
alert.msg("错误:禁止上传该类型文件!");
break;
case 'F_DUPLICATE':
alert.msg("错误:请勿重复上传该文件!");
break;
default:
alert.msg('错误代码:' + type);
break;
}
},
c.on("click",
function() {
return o(this).hasClass("disabled") ? !1 : void("ready" === k ? n.upload() : "paused" === k ? n.upload() : "uploading" === k && n.stop())
}),
p.on("click", ".retry",
function() {
n.retry()
}),
p.on("click", ".ignore",
function() {
alert.msg("已忽略")
}),
c.addClass("state-" + k),
s() });
webuploader.uploader.js
服务端接收上传文件
def webuploader_photo(request):
ret = {"status": False, "data": {"path": "", "name": ""}, "summary": ""}
target_path = "media/upload/goods/"
try:
# 获取文件对象
post_obj = request.POST
file_obj = request.FILES.get("file")
raw_name = file_obj.name
raw_id = post_obj.get("id")
postfix = raw_name.split(".")[-1]
if file_obj:
file_name = str(uuid.uuid4()) + "." + postfix
if not os.path.exists(os.path.dirname(target_path)):
os.makedirs(target_path)
file_path = os.path.join(target_path, file_name)
# os.path.join()在Linux/macOS下会以斜杠(/)分隔路径,而在Windows下则会以反斜杠(\)分隔路径,
# 故统一路径将'\'替换成'/'
file_path = file_path.replace('\\', "/")
with open(file_path, "wb") as f:
for chunk in file_obj.chunks():
f.write(chunk)
ret["status"] = True
ret["data"]['path'] = file_path
ret["data"]['name'] = raw_name
ret["data"]["id"] = raw_id
except Exception as e:
ret["summary"] = str(e)
return HttpResponse(json.dumps(ret))
python接收webuploader上传文件
webuploader真的是一个非常强大的文件上传组件
二 、服务端数据回显和编辑功能实现
html
<div class="page-container">
<div id="uploader" class="uploader" >
<div class="wrapper" class="placeholder">
<div class="file-list"></div>
<p>或将照片拖到这里,单次最多可选9张</p>
</div>
<div class="actions-area">
<div class="actions">
<div class="filePicker action">选择图片</div>
<div class="uploadFile action upload-btn disabled">上传图片</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var BASE_URL = '/static/plugins/webuploader/index.html';
//webuploader 相关配置
var uploader = new WebUploaderSupport({
server: "webuploader_photo.html",
paste: document.body,
swf: BASE_URL + "/Uploader.swf", // swf文件所处路径
support: {
uploader: "#uploader", //上传区域容器选择器
fileSize: 9, //文件总个数, -1时无限制
serverFiles: HandlerFile(),
{#[{"src":"","name":"2.PNG","attrs":{"data-server-file":true,"data-delete-url":""}}]#}
},
duplicate: true,
fileNumLimit: 9,
fileSizeLimit: 5242880,
fileSingleSizeLimit: 1048576,
headers: {
"X-CSRFToken": $.cookie('csrftoken')
},
});
</script>
html
css
.uploader {
position: relative;
padding: 15px 15px;
margin: 15px 0;
background-color: #fafafa;
box-shadow: inset 0 3px 6px rgba(0, 0, 0, .05);
border-color: #e5e5e5 #eee #eee;
border-style: solid;
border-width: 1px 0;
min-width: 250px;
} .uploader:after {
display: block;
content: "";
overflow: hidden;
clear: both;
} .uploader .message {
font-size: 16px;
margin-bottom: 20px;
} .uploader .wrapper {
text-align: center;
border: 3px dashed #ccc;
/* background: url(../images/image.png) center 93px no-repeat;*/
color: #cccccc;
font-size: 18px;
position: relative;
} .file-list {
list-style: none;
margin: 0;
padding: 0;
} .file-list:after {
display: block;
content: "";
overflow: hidden;
clear: both;
} .file-list .file-item {
float: left;
width: 150px;
height: 150px;
margin: 5px;
border: 1px solid;
overflow: hidden;
position: relative;
} .file-list .file-item img {
width: 100%;
height: 100%;
} .file-list .file-item .file-delete, .file-list .file-item .file-retry {
display: none;
position: absolute;
width: 100px;
height: 30px;
left: 50%;
margin-left: -50px;
margin-top: -15px;
top: 50%;
z-index: 1;
} /*重试时显示重试按钮*/
.file-list .file-item.retry:hover .file-retry {
display: block;
} /*删除重试按钮样式*/
.file-list .file-item button {
outline: none !important;
border: 0;
padding: 5px 12px;
opacity: 0.9;
color: #fff!important;
text-align: center;
border-radius: 3px;
display: inline-block;
margin-bottom: 0;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
} /*删除按钮*/
.file-list .file-item .file-delete button {
background: #f14641;
} .file-list .file-item .file-delete button:hover {
background: #f1281a;
} .file-list .file-item .file-retry button {
background: #daa7ff;
} .file-list .file-item .file-retry button:hover {
background: #bf8cff;
} /*重试时进度条隐藏*/
.file-list .file-item.retry .progress {
display: none!important;
} .file-list .file-item:hover .file-delete {
display: block;
} /*不能预览时的提示*/
.file-list .file-item .preview-tips {
position: absolute;
width: 100px;
height: 20px;
font-size: 16px;
left: 50%;
margin-left: -50px;
color: #949390;
margin-top: -10px;
top: 50%;
overflow: hidden;
z-index: 1;
} /*鼠标经过当前item时隐藏提示不能预览的内容*/
.file-list .file-item:hover .preview-tips {
z-index: -1;
}
/*鼠标经过当前item时如果是不能编辑则不隐藏文字*/
.file-list .file-item.not-edit:hover .preview .preview-tips {
z-index: 1;
}
.file-list .file-item.not-edit:hover .file-delete {
display: none;
} .file-list .file-item.not-edit:hover .file-retry {
display: none;
} .file-item .file-info {
position: absolute;
left: 4px;
bottom: 4px;
right: 4px;
height: 20px;
line-height: 20px;
text-indent: 5px;
background: rgba(0, 0, 0, 0.6);
color: white;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 12px;
z-index: 1;
} .file-item .state {
position: absolute;
left: 4px;
top: 4px;
right: 4px;
height: 20px;
line-height: 20px;
text-indent: 5px;
background: rgba(0, 0, 0, 0.6);
color: white;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 12px;
z-index: 1;
} .file-item .state.ready {
background: rgba(169, 64, 64, 0.6);
} .file-item .state.success {
background: rgba(68, 247, 22, 0.6);
} .file-item .state.error {
background: red;
} /*进度条*/
.file-item .progress {
display: none;
position: absolute;
width: 120px;
height: 14px;
left: 50%;
margin-left: -60px;
margin-top: -7px;
top: 50%;
} .actions-area {
height: 55px;
position: relative;
} .actions {
position: absolute;
top: 15px;
right: 0px;
} .actions .action {
display: inline-block;
float: left;
height: 40px;
} .upload-btn {
outline: none !important;
cursor: pointer;
border: 0;
padding: 10px 15px;
background: #76d67d!important;
color: #fff!important;
text-align: center;
border-radius: 3px;
overflow: hidden;
margin-left: 14px;
} .upload-btn:hover {
background: #4bb953 !important;
} .upload-btn.disabled {
background: #848080!important;
} .upload-btn.disabled:hover {
background: #404040!important;
} /*上传时使某些内容不显示*/
.uploading {
z-index: -1!important;
} .file-list .file-item.retry .file-delete {
display: block;
margin-top: 0;
} .file-list .file-item.retry button {
padding: 2px 5px;
} .file-list .file-item.retry .file-retry {
display: block;
margin-top: -30px;
} .actions-area {
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
} .actions-area button.disabled{
cursor: not-allowed;
filter: alpha(opacity=65);
-webkit-box-shadow: none;
box-shadow: none;
opacity: .65;
} .actions-area button {
margin-bottom: 0;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
} /*上传失败需要重试时未生成缩略图的提示文字隐藏*/
.file-list .file-item.retry .preview-tips {
display: none;
} .progress {
height: 20px;
margin-bottom: 20px;
overflow: hidden;
background-color: #f5f5f5;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1);
box-shadow: inset 0 1px 2px rgba(0,0,0,.1);
} .progress-bar {
float: left;
width: 0;
height: 100%;
font-size: 12px;
line-height: 20px;
color: #fff;
text-align: center;
background-color: #337ab7;
-webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);
box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);
-webkit-transition: width .6s ease;
-o-transition: width .6s ease;
transition: width .6s ease;
}
webuploader-support.css
js
function WebUploaderSupport(options) {
var that = this;
var fileStatus = {
inited: "inited", //初始状态
queued: "queued", //已经进入队列, 等待上传
progress: "progress", //上传中
complete: "complete", //上传完成
error: "error", //上传出错,可重试
interrupt: "interrupt", //上传中断,可续传
invalid: "invalid", //文件不合格,不能重试上传。会自动从队列中移除
cancelled: "cancelled" //文件被移除
};
WebUploaderSupport.fileStatus = fileStatus; var $fns = {
log: function (content) {
if(support.log && console) {
console.log(content);
}
},
logInfo: function () {
var support = that.support;
if(!support) {
this.log("WebUploader does not support the browser you are using.");
} else {
if(this.getUploader() == null) {
this.log("WebUploader has not inited, please use it after inited.");
}
}
},
getUploader: function () {
var uploader = that.uploader;
return uploader;
},
getFiles: function () {
var result = null;
var uploader = this.getUploader();
if(uploader) {
result = uploader.getFiles();
}
return result;
},
getFileSize: function (status) {
var result = 0;
var uploader = this.getUploader();
if(uploader) {
if(status != null) {
result = uploader.getFiles(status).length;
} else {
result = uploader.getFiles().length;
} }
return result;
},
getInitedFileSize: function () { //获取inited状态的文件个数
return this.getFileSize('inited');
},
retry: function (file) {
var uploader = this.getUploader();
if(uploader) {
if(that.edit) {
if(file != null) {
uploader.retry(file);
} else {
uploader.retry();
}
} else {
this.log("can't retry, because not in edit mode");
}
}
this.logInfo();
},
upload: function () {
var uploader = this.getUploader();
if(uploader) {
if(that.edit) {
uploader.upload();
} else {
this.log("can't upload, because not in edit mode");
}
}
this.logInfo();
},
removeFileWithItem: function (file) {
var uploader = that.uploader;
if(file) {
support.removeFileItem(support.getItem(file));
if(uploader) {
uploader.removeFile(file.id, true);
}
} }
};
that.$fns = $fns; options = options || {}; var support = {
$fns: {}, //公共函数
$elements: {}, //区域jquery元素
edit: true,
uploader: ".uploader", //上传区域容器选择器
dndWrapper: ".wrapper", //拖拽区域选择器
chooseFileBtn: ".filePicker", //选择文件的按钮选择器
uploadFileBtn: ".uploadFile", //上传文件的按钮选择器
fileList: ".file-list", //显示文件列表的区域选择器
fileListHeight: 150, //初始默认高度
log: false, //是否打印信息
multiple: true, //默认多选
thumbnailWidth: 150,
thumbnailHeight: 150,
fileSize: -1, //文件总个数, -1时无限制
instance: null, //uploader实例
ratio: (function () {
return window.devicePixelRatio || 1; //优化retina, 在retina下这个值是2
})(),
getActualThumbnailWidth: function () {
var that = this;
var ratio = that.ratio;
return that.thumbnailWidth * ratio;
},
getActualThumbnailHeight: function () {
var that = this;
var ratio = that.ratio;
return that.thumbnailHeight * ratio;
},
/**
* 获取不能预览的文件的样式,可覆盖(可根据名称解析后返回img对象显示)
* @param name 文件名
* @param thumbnailHeight
* @param thumbnailWidth
* @returns {jQuery}
*/
getThumbErrorPreview: function (name, thumbnailHeight, thumbnailWidth) {
var $element = $('<div class="preview"></div>').css({
height: thumbnailHeight,
width: thumbnailWidth
}).append($('<div class="preview-tips">不能预览</div>'));
return $element; //显示图片的方式
//return $('<img src="../images/preview/1.jpg">'); },
showPreview: function ($item, file) { //显示文件中的预览效果
var $preview = $('<img />');
$item.append($preview);
var uploader = this.instance;
// 缩略图大小
var thumbnailWidth = this.getActualThumbnailWidth(), thumbnailHeight = this.getActualThumbnailHeight();
this.setItemStyle($item); //设置item宽高
var self = this;
uploader.makeThumb(file, function (error, src) {
if (error) {
$preview.replaceWith(self.getThumbErrorPreview(file.name, self.thumbnailHeight, self.thumbnailWidth));
return;
}
$preview.attr('src', src); }, thumbnailWidth, thumbnailHeight);
},
getItem: function (file) { //获取$item
return $("#" + file.id);
},
setItemStyle: function ($item) { //设置缩略图所在容器的宽高,默认是均150px,用于加载文件预览时设置
if($item) {
var that = this;
var thumbnailWidth = that.thumbnailWidth, thumbnailHeight = that.thumbnailHeight;
$item.css({width: thumbnailWidth, height: thumbnailHeight}); //设置$item宽高
}
},
loadUploadFileBtnStyle: function () { //用于加载上传按钮的样式
var $fns = this.$fns;
var $uploadFileBtn = this.$elements.$uploadFileBtn;
if($fns && $uploadFileBtn) {
var initedSize = $fns.getInitedFileSize();
if (initedSize === 0) { //inited 文件个数
$uploadFileBtn.addClass("disabled"); //上传按钮禁用
} else {
$uploadFileBtn.removeClass("disabled"); //移除上传按钮的禁用样式
}
}
},
retryFile: function ($item, file) {
var $fns = this.$fns;
$fns.retry(file);
},
renderItem: function (isFile, data) {
var name = data.name || "";
var html =
'<div class="file-item thumbnail">' +
'<div class="file-info">' + name + '</div>' +
'<div class="file-operations">' +
'<div class="file-delete">' + '<button type="button">' + '删除</button></div>' +
'<div class="file-retry">' + '<button type="button">' + '重试</button></div>' +
'</div>' +
'<div class="progress">' +
'<div class="progress-bar"></div>' +
'</div>' +
'</div>';
var $item = $(html); if (!isFile) {
//服务端显示数据时
var $preview; //根据文件后缀进行展示预览结果
if(/(.jpg|.png|.gif|.bmp|.jpeg)$/.test(name.toLocaleLowerCase())) {
$preview = $('<img src="'+ data.src + '"/>');
//自定义添加
var $input =$('<input type="text" value="'+ data.src +'" class="hidden" >') ;
$item.append($input);
} else {
$preview = this.getThumbErrorPreview(data.name, this.thumbnailHeight, this.thumbnailWidth);
}
$item.append($preview);
} else {
$item.attr("id", data.id);
$item.append('<div class="state ready">等待上传...</div>');
this.showPreview($item, data); //显示预览效果
}
return $item[0];
},
fileQueued: function (file) { //文件被添加进队列
var self = this;
var $item = $(this.renderItem(true, file));
var $fileList = this.$elements.$fileList;
$fileList.append($item); //显示在文件列表中
self.loadUploadFileBtnStyle(); //加载上传按钮样式
$item.on("click", 'button', function () {
var $this = $(this);
if($this.parents(".file-retry")[0]) {
self.retryFile($item, file);
} else if ($this.parents(".file-delete")[0]) {
self.deleteFile($item, file, self.deleteServerFileCallback, self.$fns.removeFileWithItem);
}
});
self.loadChooseFileBtnStyle(this.$elements.$chooseFileBtn, this.$elements.$uploadFileBtn);
},
fileDequeued: function (file) {
this.loadUploadFileBtnStyle();
},
uploadProgress: function (file, percentage) { //文件上传过程中创建进度条
var $item = this.getItem(file);
$item.find('.file-delete, .preview-tips').addClass("uploading"); //隐藏删除按钮、提示文字
$item.removeClass("retry"); //移除重试class
$item.find('.progress').show(); //显示进度条
var $percent = $item.find('.progress .progress-bar');
$percent.css('width', percentage * 100 + '%');
},
uploadComplete: function (file) { //完成上传时,无论成功或者失败
var $item = this.getItem(file);
$item.find('.progress').fadeOut();
$item.find('.file-delete, .preview-tips').removeClass("uploading"); //显示删除按钮、提示文字 var $uploadFileBtn = this.$elements.$uploadFileBtn;
var $chooseFileBtn = this.$elements.$chooseFileBtn; this.loadChooseFileBtnStyle($chooseFileBtn, $uploadFileBtn);
this.loadUploadFileBtnStyle();
},
uploadSuccess: function (file, response) {
// 文件上传完成后
var res=JSON.parse(response._raw);//这里可以得到后台返回的数据
var $item = this.getItem(file),
$state = $item.find('.state');
$item.find('.progress').hide();
if (res.status) { //上传成功时
this.uploadSuccessCallbck($item, res); //用于标识为服务端文件
if (!$state.hasClass('success')) {
$state.attr("class", "state success");
$state.text('上传成功');
}
$item.removeClass("retry");
} else {
if (!$state.hasClass('error')) {
$state.attr("class", "state error");
$state.text('上传失败');
}
$item.addClass("retry");
}
},
uploadSuccessCallbck: function ($item, data) { //上传文件成功时的回调,用于标识为服务端文件
console.log("$item",$item)
if($item && data) {
var input = document.createElement("input");
console.log(data.data)
var data = data.data
input.type="hidden";
input.name=data.id;
input.value="/"+data.path;
$item .append(input);
}
},
/***
* 当文件被加入队列之前触发,若返回false则此文件不会被添加进入队列
* @param file
* @returns {boolean} 为true时可以添加到webuploader中并进行显示
*/
beforeFileQueued: function(file) {
var fileSize = this.fileSize; //获取当前总个数
if(fileSize <) { //无限制个数
return true;
}
var currentFileSize = this.getCurrentFileSize(); //当前总个数
var flag = false;
var edit = this.edit;
if(edit) { //可编辑模式时
if(currentFileSize < fileSize) {
flag = true;
}
}
//执行beforeFileQueuedCallback回调函数
this.beforeFileQueuedCallback(edit, flag, file, fileSize, currentFileSize);
return flag;
}, /**
* 当文件被加入队列返回结果之前触发
* @param edit 是否可编辑
* @param result 是否会添加并显示
* @param file --- file对象
* @param fileSize --- 总文件个数
* @param currentFileSize --- 当前文件个数
*/
beforeFileQueuedCallback: function (edit, result, file, fileSize, currentFileSize) {
},
/**
* 当validate不通过时触发
* @param type
* Q_EXCEED_SIZE_LIMIT 在设置了Q_EXCEED_SIZE_LIMIT且尝试给uploader添加的文件总大小超出这个值时
* Q_TYPE_DENIED 当文件类型不满足时
* Q_EXCEED_NUM_LIMIT 在设置了fileNumLimit且尝试给uploader添加的文件数量超出这个值时
*/
errorTypeHanlder: function (type, file) { },
uploadError: function (file) { //文件上传失败后
console.log("uploadError")
var $item = this.getItem(file),
$state = $item.find('.state');
if (!$state.hasClass('error')) {
$state.attr("class", "state error");
$state.text('上传失败');
}
$item.addClass("retry");
this.loadUploadFileBtnStyle(); this.uploadErrorAfter(file);
},
/**
* 上传失败后执行
* @param file
*/
uploadErrorAfter: function (file) { },
uploadFinished: function () {}, //文件上传完后触发
serverFileAttrName: "data-server-file", //服务端文件的属性名称
getIsServerFile: function ($item) { //判断文件是否是服务端文件
var val = $item && $item.attr(this.serverFileAttrName);
if(val && val === "true") {
return true;
}
return false;
},
getServerFileSize: function () { //获取服务端文件的个数
var $fileList = this.$elements.$fileList;
var size = 0;
var serverFileAttrName = this.serverFileAttrName;
if($fileList) {
size = $fileList.find(".file-item["+serverFileAttrName+"='true']").size();
}
return size;
},
getItemSize: function () { //获取当前item的文件个数
var $fileList = this.$elements.$fileList;
var size = 0;
if($fileList) {
size = $fileList.find(".file-item").size();
}
return size;
},
getCurrentFileSize: function () { //获取当前uploader实例中文件的个数
var fileStatus = WebUploaderSupport.fileStatus;
var $fns = this.$fns;
var initedSize = $fns.getFileSize(fileStatus.inited); //初始状态个数
var errorSize = $fns.getFileSize(fileStatus.error); //上传失败个数
var size = initedSize + errorSize + this.getServerFileSize();//最终加上服务端文件个数
var itemSize = this.getItemSize();
var result = itemSize > size ? itemSize : size;
return result;
},
removeFileItem: function($item) { //移除$item
if($item && $item[0]) {
$item.off().remove();
}
},
deleteFile: function ($item, file, deleteServerFileCallback, removeFileWithItem) { //删除文件的处理逻辑,包含服务端
if(this.getIsServerFile($item)) { //服务端时
if(this.edit) {
this.deleteServerFile($item, deleteServerFileCallback);
} else {
this.$fns.log("can't delete server file");
}
}
else {
if(removeFileWithItem && file) {
removeFileWithItem(file);
}
var $chooseFileBtn = this.$elements.$chooseFileBtn, $uploadFileBtn = this.$elements.$uploadFileBtn;
this.loadChooseFileBtnStyle($chooseFileBtn, $uploadFileBtn);
}
}, deleteServerFileAttrName: "data-delete-url",
/**
* 删除服务端文件(依赖于getIsServerFile的判断结果)的业务操作,可根据实际覆盖重写(support配置中直接重写该函数即可)
* @param $item
* @param deleteServerFileCallback
*/
deleteServerFile: function ($item, deleteServerFileCallback) {
var self = this;
//获取删除的url
var url = $item && $item.attr(self.deleteServerFileAttrName);
if(url) {
$.ajax({
dataType: "json",
type: "post",
url: url,
success: function (json) {
if(deleteServerFileCallback && typeof deleteServerFileCallback === "function") {
deleteServerFileCallback(self, $item, json); //通过callback执行业务操作
var $chooseFileBtn = self.$elements.$chooseFileBtn, $uploadFileBtn = self.$elements.$uploadFileBtn;
self.loadChooseFileBtnStyle($chooseFileBtn, $uploadFileBtn);
}
}
});
}
},
/**
* deleteServerFile 响应成功时的回调处理,可根据实际覆盖重写
* @param self 当前对象
* @param $item
* @param data
*/
deleteServerFileCallback: function (self, $item, data) {
if(data.status) {
self.removeFileItem($item);
} else {
alert(data.content);
}
},
serverFiles: [], //加载服务端的数据,当前为 [{name:string, src: string, attrs: {}}]
init: function (data, $fileList, $chooseFileBtn, $uploadFileBtn) { //初始化服务端数据,及加载样式 var self = this;
var edit = self.edit;
var $files = null; var thumbnailHeight = self.thumbnailHeight;
$fileList.css({"min-height": thumbnailHeight + 20}); //设置该区域最小高度为thumbnailHeight + 20px //加载服务端数据
if(data && data.length > 0) {
for(var i in data) {
var item = data[i];
var $item = $(this.renderItem(false, item)); if(!edit) {
$item.addClass("not-edit");
} self.setItemStyle($item); //以缩略图大小设置$item宽高 if($item && item) {
var attrs = item.attrs;
for(var key in attrs) { //设置$item属性值
$item.attr(key, attrs[key]);
}
}
if(i === "0") {
$files = $item;
} else {
$files = $files.add($item);
}
}
}
if($files) { //加载服务端数据
$fileList.append($files);
$files.on('click', '.file-delete button', function () {
var $item = $(this).parents(".file-item");
self.deleteFile($item, null, self.deleteServerFileCallback);
});
} self.loadChooseFileBtnStyle($chooseFileBtn, $uploadFileBtn);
},
editChange: function (edit) { //用于根据edit改变时进行设置webuploader模式
var that = this;
that.edit = edit;
var $chooseFileBtn = that.$elements.$chooseFileBtn, $uploadFileBtn = that.$elements.$uploadFileBtn;
var $fileList = that.$elements.$fileList;
if(edit) {
$fileList.children().removeClass("not-edit");
} else {
$fileList.children().addClass("not-edit");
}
that.loadChooseFileBtnStyle($chooseFileBtn, $uploadFileBtn);
},
getChooseFileLabel: function ($chooseFileBtn) { //获取当前上传文件按钮对应的label,该label用于触发选择文件
var $label = null;
if($chooseFileBtn) {
if($chooseFileBtn.hasClass("webuploader-container")) {
$label = $chooseFileBtn.find(".webuploader-element-invisible").next("label");
} else {
$label = $(".webuploader-container").not(this.chooseFileBtn).find(".webuploader-element-invisible").next("label");
}
}
return $label;
},
loadChooseFileBtnStyle: function ($chooseFileBtn, $uploadFileBtn) { //根据文件个数进行展示选择文件的按钮(用于上传完成时,删除文件时,添加到队列时, 初次加载服务端数据时)
var that = this;
var $fns = that.$fns;
var fileSize = that.fileSize;
var $actions = $chooseFileBtn.parents(".actions");
var $actionsArea = $actions.parent(".actions-area");
var $label = that.getChooseFileLabel($chooseFileBtn); if (that.edit) { //可编辑时
$actionsArea.css("height", "");
$actions.show();
var uploader = $fns.getUploader();
if(uploader) {
uploader.refresh(); //解决label按钮点击无反应
}
if (fileSize > 0) {
var currentSize = that.getCurrentFileSize();
if (fileSize === currentSize) {
$label && $label.hide();
$chooseFileBtn.hide();
$uploadFileBtn.addClass("right");
} else {
$label && $label.show();
$chooseFileBtn.show();
$uploadFileBtn.removeClass("right");
}
} else {
$label && $label.show();
$chooseFileBtn.show();
$uploadFileBtn.removeClass("right");
}
} else { //不可编辑时 $actions.hide();
$actionsArea.css("height", 10); if ($label) {
$label.hide();
}
}
}
}; support = $.extend(support, options.support); support.$fns = $fns; //设置support方法 that.supports = support; var multiple = support.multiple; delete options.support; //删除额外的support属性 var $uploader = $(support.uploader),
$chooseFileBtn = $uploader.find(support.chooseFileBtn), //选择文件的按钮选择器
$fileList = $uploader.find(support.fileList), //显示文件列表的区域
$uploadFileBtn = $uploader.find(support.uploadFileBtn), //上传文件的按钮
$dndWrapper = $uploader.find(support.dndWrapper); //支持拖拽到此区域 var $elements = {
$uploader: $uploader,
$chooseFileBtn: $chooseFileBtn,
$fileList: $fileList,
$uploadFileBtn: $uploadFileBtn,
$dndWrapper: $dndWrapper
}; support.$elements = $elements; var defaultOption = {
accept: {
title: 'Images',
extensions: 'gif,jpg,jpeg,bmp,png',
mimeTypes: 'image/!*'
},
pick: {
id: $chooseFileBtn,
multiple: multiple
},
disableGlobalDnd: true,
dnd: $dndWrapper, //支持拖拽到此区域
resize: false,
compress: false, //不压缩图片,原图
swf: 'Uploader.swf' // swf文件路径
}; var currentOptions = $.extend(true, {}, defaultOption, options); //当期webuploader的配置, options中的优先级最高 if(document.all || window.ActiveXObject || "ActiveXObject" in window) {
if(currentOptions.paste != null) {
currentOptions.paste = null;
$fns.log("ie is not support paste");
}
} that.edit = support.edit;
that.support = WebUploader.Uploader.support(); //获取是否支持webuploader上传 jQuery(function() {
var $ = jQuery;
$fileList.css({"min-height": support.fileListHeight + 20}); var uploader;
try {
if(!that.support) {
support.init(support.serverFiles, $fileList, $chooseFileBtn, $uploadFileBtn);
$fns.log("WebUploader does not support the browser you are using.");
return;
} else {
uploader = WebUploader.create(currentOptions); //实例化webuploader
support.instance = uploader;
support.init(support.serverFiles, $fileList, $chooseFileBtn, $uploadFileBtn);
} } catch (e) {
if(console) {
console.log(e);
}
} if(uploader) { that.uploader = uploader; if($uploadFileBtn && $uploadFileBtn[0]) {
$uploadFileBtn.click(function () {
$fns.upload();
});
} //文件被添加进队列时
uploader.on('fileQueued', function (file) {
support.fileQueued && support.fileQueued.apply(support, arguments);
}); //移除文件时
uploader.on('fileDequeued', function (file) {
support.fileDequeued && support.fileDequeued.apply(support, arguments);
}); uploader.on('uploadProgress', function (file, percentage) {
support.uploadProgress && support.uploadProgress.apply(support, arguments);
}); //完成上传时,无论成功或者失败
uploader.on('uploadComplete', function (file) {
support.uploadComplete && support.uploadComplete.apply(support, arguments);
}); // 文件上传完成后,添加相应的样式(响应成功)
uploader.on('uploadSuccess', function (file, data) {
support.uploadSuccess && support.uploadSuccess.apply(support, arguments);
}); // 文件上传失败,显示上传出错(上传失败出现错误状态码时)
uploader.on('uploadError', function (file) {
support.uploadError && support.uploadError.apply(support, arguments);
});
// 当文件被加入队列之前触
uploader.on('beforeFileQueued', function (file) {
return support.beforeFileQueued && support.beforeFileQueued.apply(support, arguments); }); //当前uploader实例文件上传完成后触发
uploader.on("uploadFinished", function () {
support.uploadFinished && support.uploadFinished.apply(support, arguments);
}); uploader.on('error', function () {
support.errorTypeHanlder && support.errorTypeHanlder.apply(support, arguments);
}); }
}); } //上传该uploader实例的文件
WebUploaderSupport.prototype.upload = function () {
this.$fns.upload();
}
//判断是否正在上传中
WebUploaderSupport.prototype.isInProgress = function () {
var flag = false;
var uploader = this.uploader;
if(uploader) {
flag = uploader.isInProgress();
}
this.$fns.logInfo();
return flag;
} WebUploaderSupport.prototype.retry = function () {
this.$fns.retry();
} WebUploaderSupport.prototype.getSupports = function () {
var supports = this.supports;
return supports;
}
//更换模式
WebUploaderSupport.prototype.editChange = function (edit) {
if(typeof edit != "boolean") {
throw new Error("the param type must be boolean");
}
var supports = this.supports;
this.edit = edit;
supports.editChange(edit);
}
webloader-support.js
参考github上的一个朋友对webuploader 的封装:https://github.com/joker-pper/WebUploaderSupport
webuploader 多图片上传的更多相关文章
- Asp.Net Mvc 使用WebUploader 多图片上传
来博客园有一个月了,哈哈.在这里学到了很多东西.今天也来试着分享一下学到的东西.希望能和大家做朋友共同进步. 最近由于项目需要上传多张图片,对于我这只菜鸟来说,以前上传图片都是直接拖得控件啊,而且还是 ...
- WebUploader文件图片上传插件的使用
最近在项目中用到了百度的文件图片上传插件WebUploader.分享给大家 需要在http://fex.baidu.com/webuploader/download.html点击打开链接下载WebUp ...
- WebUploader压缩图片上传
WebUploader,由Baidu FEX 团队开发,以H5为主,FLASH为辅,兼容 IE6+,iOS 6+, android 4+,采用大文件分片并发上传,极大的提高了文件上传效率,看了官方文档 ...
- Webuploader 简单图片上传 支持多图上传
简介: 通过webuploader 实现简单的图片上传功能,支持多张图上传 官方文档传送门:http://fex.baidu.com/webuploader/getting-started.html# ...
- Yii2结合webuploader实现图片上传
js中 uploader = WebUploader.create({ // 自动上传. auto : true, // swf文件路径 swf : 'webuploader/Uploader.swf ...
- 百度上传工具webuploader,图片上传附加参数
项目中需要上传视频,图片等资源.最先做的是上传图片,开始在网上找了一款野鸡插件,可以实现图片上传预览(无需传到后台).但是最近这个插件出了莫名的问题,不易修复,一怒之下,还是决定找个大点的,靠谱的插件 ...
- 图片上传webuploader
/** * 基于jquery的图片上传控件 */!function ($) { "use strict"; //定义上传事件 var upImgEvent = { fileQueu ...
- 妈蛋:kinMaxShow旋转木马异常,WebUploader图片上传坑爹,图像被压缩
今天晚上在改造轮播图. 原来的代码是这种: <div> <img src="${static}/image/index/banner/`.jpg" /> & ...
- 图片上传组件webuploader
前端组件webuploader 当时也是搞了很久参考这种demo,但是没记.现在事后大致总结下.直接上大概代码(我使用asp.net MVC来做的): 执行顺序:(get)Record/Add——A ...
随机推荐
- mysql实现经纬度计算两个坐标之间的距离
DELIMITER $$CREATE DEFINER = CURRENT_USER FUNCTION `getDistance`(`lon1` float,`lat1` float,`lon2` fl ...
- C++ 运算符重载一(二元运算符重载)
//二元运算符重载 #include<iostream> using namespace std; class Point { public: Point(int x,int y){ th ...
- TensorFlow基础笔记(4) Tensor Transformation
https://segmentfault.com/a/1190000008793389 抽取 tf.slice(input_, begin, size, name=None):按照指定的下标范围抽取连 ...
- Spring Cloud对于中小型互联网公司来说是一种福音
Spring Cloud对于中小型互联网公司来说是一种福音,因为这类公司往往没有实力或者没有足够的资金投入去开发自己的分布式系统基础设施,使用Spring Cloud一站式解决方案能在从容应对业务发展 ...
- 算法优化:rgb向yuv的转化最优算法
朋友曾经给我推荐了一个有关代码优化的pdf文档<让你的软件飞起来>,看完之后,感受颇深.为了推广其,同时也为了自己加深印象,故将其总结为word文档.下面就是其的详细内容总结,希望能于己于 ...
- 【BZOJ】1690: [Usaco2007 Dec]奶牛的旅行(分数规划+spfa)
http://www.lydsy.com/JudgeOnline/problem.php?id=1690 第一题不是水题的题.. 分数规划.. T-T 百度吧..http://blog.csdn.ne ...
- 彻底明确Android中AIDL及其使用
1.为什么要有AIDL? 不管学什么东西,最先得弄明确为什么要有这个东西.不要说存在即是合理.存在肯定合理,可是你还是没有明确. 对于AIDL有一些人的浅显概念就是,AIDL能够跨进程訪问其它应用程序 ...
- springmvc+mybatis+maven项目框架搭建
项目的目录
- [转]Linux动态库的种种要点
linux下使用动态库,基本用起来还是很容易.但如果我们的程序中大量使用动态库来实现各种框架/插件,那么就会遇到一些坑,掌握这些坑才有利于程序更稳健地运行. 本篇先谈谈动态库符号方面的问题. 测试代码 ...
- 指针*pbuffer和getchar 读取字符串
在C语言入门教材里看到这一段代码,没看懂是什么意思.char buffer[10];char *pbuffer = buffer;while( (*pbuffer++ = getchar() )!= ...