vue-simple
Version:
Use Vue in the simplest and easiest way, contain more than one of plugins and other to do that, i hope you will like it.
130 lines (103 loc) • 4.05 kB
JavaScript
import * as utils from '../../utils';
/**
* 给指定元素绑定文件拖拽事件
* @param {HTMLElement} el HTML元素
* @param {Boolean} multiple 是否可多选
* @param {String} accept 指定能选择的文件类型 mime
* @param {Function} change 当选择文件后调用的回调
* @param {Function} [enter] 当拖拽进入区域内时的回调
* @param {Function} [leave] 当拖拽离开区域内时的回调
* @param {Function} [dragover] 当拖拽进入区域后在该区域内移动时的回调
* @constructor
*/
function FileDraggerBinder({ el, multiple, accept, change, enter, leave, dragover }) {
const self = this;
let params = { el, multiple, accept, change, enter, leave, dragover };
this.init = () => {
// 拖拽事件
// drop
params.el.addEventListener('drop', _drop);
// dragenter
params.el.addEventListener('dragenter', _dragenter);
// dragover
params.el.addEventListener('dragover', _dragover);
// dragleave
params.el.addEventListener('dragleave', _dragleave);
};
this.destory = () => {
params.el.removeEventListener('drop', _drop);
params.el.removeEventListener('dragenter', _dragenter);
params.el.removeEventListener('dragover', _dragover);
params.el.removeEventListener('dragleave', _dragleave);
params = null;
};
this.checkAccept = files => files.filter(file => {
const { type, name, size } = file;
const extension = name.indexOf('.') > -1 ? `.${name.split('.').pop()}` : ''; // 扩展名 如 .jpg
const baseType = type.replace(/\/.*$/, ''); // 文件类型 如 image/jpeg,结果为 image
return params.accept.split(',').filter(mimeType => mimeType.trim()).some(acceptedType => {
// 文件夹或非正常文件的大小为 0 kb
if (!size || !type) return false;
// 直接比较扩展名(假如 accept 设置成了扩展名)
// 不考虑 application/vnd.ms-excel 吗?
if (/\..+$/.test(acceptedType)) {
return extension === acceptedType;
}
// 对比 MIME 的前部分,如 image/jpeg 的 image
if (/\/\*$/.test(acceptedType)) {
return baseType === acceptedType.replace(/\/\*$/, '');
}
// 直接比较文件 mime 和当前 mimetype
if (/^[^\/]+\/[^\/]+$/.test(acceptedType)) {
return type === acceptedType;
}
return false;
});
});
// 获取文件类型
this.getFiles = dataTransfer => {
let files = null;
if (_isSupportEntry(dataTransfer)) {
const items = [...dataTransfer.items];
files = [];
items.forEach(item => {
const entry = item.webkitGetAsEntry();
// 暂不处理文件夹
// if (entry.isDirectory) {
// console.warn('isDirectory:', entry);
// }
// 只需要保留拖拽进来的文件类型
if (entry.isFile) {
files.push(item.getAsFile());
}
});
}
else {
files = [...dataTransfer.files];
}
return files;
};
function _isSupportEntry(dataTransfer) {
return dataTransfer.items && dataTransfer.items[0] && dataTransfer.items[0].webkitGetAsEntry;
}
function _drop(event) {
if (event.preventDefault) event.preventDefault();
const fileList = self.getFiles(event.dataTransfer);
const acceptFiles = self.checkAccept(fileList);
if (utils.isFunction(params.change)) params.change.call(params.el, acceptFiles);
// if (utils.isFunction(params.leave)) params.leave.call(params.el, event);
}
function _dragenter(event) {
if (event.preventDefault) event.preventDefault();
if (utils.isFunction(params.enter)) params.enter.call(params.el, event);
}
function _dragover(event) {
if (event.preventDefault) event.preventDefault();
if (utils.isFunction(params.dragover)) params.dragover.call(params.el, event);
}
function _dragleave(event) {
if (event.preventDefault) event.preventDefault();
if (utils.isFunction(params.leave)) params.leave.call(params.el, event);
}
}
export default FileDraggerBinder;