(function($) {
// 当domReady的时候开始初始化
$(function() {
var $wrap = $('#uploader'),
// 图片容器
$queue = $('
')
.appendTo($wrap.find('.queueList')),
// 状态栏,包括进度和控制按钮
$statusBar = $wrap.find('.statusBar'),
// 文件总体选择信息。
$info = $statusBar.find('.info'),
// 上传按钮
$upload = $wrap.find('.uploadBtn'),
// 没选择文件之前的内容。
$placeHolder = $wrap.find('.placeholder'),
$progress = $statusBar.find('.progress').hide(),
// 添加的文件数量
fileCount = 0,
// 添加的文件总大小
fileSize = 0,
// 可能有pedding, ready, uploading, confirm, done.
state = 'pedding',
// 所有文件的进度信息,key为file id
percentages = {},
// WebUploader实例
uploader;
// 实例化
uploader = WebUploader.create({
pick: '#filePicker',
dnd: '#dndArea',
chunked: true,
accept: '',
server: './server/fileupload.php',
// server: 'http://www.2betop.net/fileupload.php',
});
// 添加“添加文件”的按钮,
uploader.addButton({
id: '#filePicker2',
label: '继续添加'
});
// 当有文件添加进来时执行,负责view的创建
function addFile(file) {
var $li = $('' +
'' + file.name + '
' +
'' +
'
' +
''),
$btns = $('' +
'删除' + '
').appendTo($li),
$prgress = $li.find('p.progress span'),
$wrap = $li.find('p.imgWrap'),
$info = $(''),
showError = function(code) {
switch (code) {
case 'interrupt':
text = '上传暂停';
break;
default:
text = '上传失败,请重试';
break;
}
$info.text(text).appendTo($li);
};
if (file.getStatus() === 'invalid') {
showError(file.statusText);
} else {
$wrap.text('不能预览');
percentages[file.id] = [file.size, 0];
file.rotation = 0;
}
file.on('statuschange', function(cur, prev) {
if (prev === 'progress') {
$prgress.hide().width(0);
} else if (prev === 'queued') {
$li.off('mouseenter mouseleave');
$btns.remove();
}
// 成功
if (cur === 'error' || cur === 'invalid') {
showError(file.statusText);
percentages[file.id][1] = 1;
} else if (cur === 'interrupt') {
showError('interrupt');
} else if (cur === 'queued') {
percentages[file.id][1] = 0;
} else if (cur === 'progress') {
$info.remove();
$prgress.css({
display: 'block',
width: '10%'
});
} else if (cur === 'complete') {
$li.append('');
}
$li.removeClass('state-' + prev).addClass('state-' + cur);
});
$li.on('mouseenter', function() {
$btns.stop().animate({
height: 30
});
});
$li.on('mouseleave', function() {
$btns.stop().animate({
height: 0
});
});
$btns.on('click', 'span', function() {
uploader.removeFile(file);
});
$li.appendTo($queue);
}
// 负责view的销毁
function removeFile(file) {
var $li = $('#' + file.id);
delete percentages[file.id];
updateTotalProgress();
$li.off().find('.file-panel').off().end().remove();
}
function updateTotalProgress() {
var loaded = 0,
total = 0,
spans = $progress.children(),
percent;
$.each(percentages, function(k, v) {
total += v[0];
loaded += v[0] * v[1];
});
percent = total ? loaded / total : 0;
spans.eq(0).text(Math.round(percent * 100) + '%');
spans.eq(1).css('width', Math.round(percent * 100) + '%');
updateStatus();
}
function updateStatus() {
var text = '',
stats;
if (state === 'ready') {
text = '选中' + fileCount + '张图片,共' +
WebUploader.formatSize(fileSize) + '。';
} else if (state === 'confirm') {
stats = uploader.getStats();
if (stats.uploadFailNum) {
text = '已成功上传' + stats.successNum + '张照片至XX相册,' +
stats.uploadFailNum + '张照片上传失败,重新上传失败图片或忽略'
}
} else {
stats = uploader.getStats();
text = '共' + fileCount + '张(' +
WebUploader.formatSize(fileSize) +
'),已上传' + stats.successNum + '张';
if (stats.uploadFailNum) {
text += ',失败' + stats.uploadFailNum + '张';
}
}
$info.html(text);
}
function setState(val) {
var file, stats;
if (val === state) {
return;
}
$upload.removeClass('state-' + state);
$upload.addClass('state-' + val);
state = val;
switch (state) {
case 'pedding':
$placeHolder.removeClass('element-invisible');
$queue.hide();
$statusBar.addClass('element-invisible');
uploader.refresh();
break;
case 'ready':
$placeHolder.addClass('element-invisible');
$('#filePicker2').removeClass('element-invisible');
$queue.show();
$statusBar.removeClass('element-invisible');
uploader.refresh();
break;
case 'uploading':
$('#filePicker2').addClass('element-invisible');
$progress.show();
$upload.text('暂停上传');
break;
case 'paused':
$progress.show();
$upload.text('继续上传');
break;
case 'confirm':
$progress.hide();
$upload.text('开始上传').addClass('disabled');
stats = uploader.getStats();
if (stats.successNum && !stats.uploadFailNum) {
setState('finish');
return;
}
break;
case 'finish':
stats = uploader.getStats();
if (stats.successNum) {
alert('上传成功');
} else {
// 没有成功的图片,重设
state = 'done';
location.reload();
}
break;
}
updateStatus();
}
uploader.onUploadProgress = function(file, percentage) {
var $li = $('#' + file.id),
$percent = $li.find('.progress span');
$percent.css('width', percentage * 100 + '%');
percentages[file.id][1] = percentage;
updateTotalProgress();
};
uploader.onFileQueued = function(file) {
fileCount++;
fileSize += file.size;
if (fileCount === 1) {
$placeHolder.addClass('element-invisible');
$statusBar.show();
}
addFile(file);
setState('ready');
updateTotalProgress();
};
uploader.onFileDequeued = function(file) {
fileCount--;
fileSize -= file.size;
if (!fileCount) {
setState('pedding');
}
removeFile(file);
updateTotalProgress();
};
uploader.on('all', function(type) {
var stats;
switch (type) {
case 'uploadFinished':
setState('confirm');
break;
case 'startUpload':
setState('uploading');
break;
case 'stopUpload':
setState('paused');
break;
}
});
uploader.onError = function(code) {
alert('Eroor: ' + code);
};
$upload.on('click', function() {
if ($(this).hasClass('disabled')) {
return false;
}
if (state === 'ready') {
uploader.upload();
} else if (state === 'paused') {
uploader.upload();
} else if (state === 'uploading') {
uploader.stop();
}
});
$info.on('click', '.retry', function() {
uploader.retry();
});
$info.on('click', '.ignore', function() {
alert('todo');
});
$upload.addClass('state-' + state);
updateTotalProgress();
});
})(jQuery);
(function($) {
// 扩展md5逻辑
var Uploader = WebUploader.Uploader;
var fr;
function readContent(file, cb) {
var chunkSize = 2 * 1024 * 1024,
chunks = Math.ceil(file.size / chunkSize),
chunk = 0,
ret = '',
blobSlice = file.mozSlice || file.webkitSlice || file.slice,
loadNext;
fr = fr || new FileReader;
loadNext = function() {
var start, end;
start = chunk * chunkSize;
end = start + chunkSize >= file.size ? file.size : start + chunkSize;
fr.onload = function(e) {
ret += fr.result;
fr.result = null;
};
fr.onloadend = function() {
fr.onload = fr.onloadend = null;
if (++chunk < chunks) {
setTimeout(loadNext, 1);
} else {
fr.readAsBinaryString(new Blob(['a'], {
type: 'text/plain'
}));
cb(ret);
ret = loadNext = blobSlice = file = null;
}
};
fr.readAsBinaryString(blobSlice.call(file, start, end));
};
loadNext();
}
function Md5File(file, callback) {
console.time('get md5: ' + file.name);
readContent(file, function(ret) {
ret = md5(ret);
console.timeEnd('get md5: ' + file.name);
setTimeout(function() {
callback(ret);
}, 1);
});
}
Uploader.register({
'before-send-file': 'preupload'
}, {
preupload: function(file) {
var me = this,
owner = this.owner,
server = me.options.server,
deferred = WebUploader.Deferred(),
blob = file.source.getSource();
Md5File(blob, function(ret) {
$.ajax(server, {
dataType: 'json',
data: {
md5: ret
},
success: function( response ) {
if ( response.exist ) {
owner.skipFile( file );
var log = $('#'+file.id).find('p.imgWrap')
log.text('文件重复,已跳过');
}
deferred.resolve( true );
}
});
});
return deferred.promise();
}
});
})(jQuery);