测试

修改https://github.com/tkvw/jQuery-File-Upload/blob/master/basic-plus.html

var node = $('<p id="chuck" class="preview"/>')
.append($('<span/>').text(file.name));

给p增加id和class,在页面加载后,

打开浏览器的console,然后手动执行,然后单击图片。会发现这个事件是会触发的

$(".preview").on("click", function(){
alert("test");
})

但是jquery.fileupload-image-editor.js中的没有触发,事件应该是绑定了

手动移除事件

$(".preview").off("click");  https://stackoverflow.com/questions/209029/best-way-to-remove-an-event-handler-in-jquery

分析

1.jquery.fileupload-image-editor.js定义了uploadImageEditorPreviewSelector

uploadImageEditorPreviewSelector: 'click .preview',

2,.jquery.fileupload-ui.js中定义了filesContainer
// The container for the list of files. If undefined, it is set to
// an element with class "files" inside of the widget element:
filesContainer: undefined,

_initEventHandlers: function () {
this._super();

var handlers = {};
handlers[this.options.uploadImageEditorPreviewSelector] = this._previewHandler.bind(this);

this._on(this.options.filesContainer, handlers);
},

文件上传之后

jquery.fileupload.js中_onAdd: function (e, data) {

that._initResponseObject(newData);
that._initProgressObject(newData);
that._addConvenienceMethods(e, newData);
result = that._trigger(
'add',
$.Event('add', {delegatedEvent: e}),
newData
);
return result;

_initResponseObject: function (obj) {
var prop;
if (obj._response) {
for (prop in obj._response) {
if (obj._response.hasOwnProperty(prop)) {
delete obj._response[prop];
}
}
} else {
obj._response = {};
}
},

_initProgressObject: function (obj) {
var progress = {
loaded: 0,
total: 0,
bitrate: 0
};
if (obj._progress) {
$.extend(obj._progress, progress);
} else {
obj._progress = progress;
}
},

 // Adds convenience methods to the data callback argument:
_addConvenienceMethods: function (e, data) {
var that = this,
getPromise = function (args) {
return $.Deferred().resolveWith(that, args).promise();
};
data.process = function (resolveFunc, rejectFunc) {
if (resolveFunc || rejectFunc) {
data._processQueue = this._processQueue =
(this._processQueue || getPromise([this])).then(
function () {
if (data.errorThrown) {
return $.Deferred()
.rejectWith(that, [data]).promise();
}
return getPromise(arguments);
}
).then(resolveFunc, rejectFunc);
}
return this._processQueue || getPromise([this]);
};
data.submit = function () {
if (this.state() !== 'pending') {
data.jqXHR = this.jqXHR =
(that._trigger(
'submit',
$.Event('submit', {delegatedEvent: e}),
this
) !== false) && that._onSend(e, this);
}
return this.jqXHR || that._getXHRPromise();
};
data.abort = function () {
if (this.jqXHR) {
return this.jqXHR.abort();
}
this.errorThrown = 'abort';
that._trigger('fail', null, this);
return that._getXHRPromise(false);
};
data.state = function () {
if (this.jqXHR) {
return that._getDeferredState(this.jqXHR);
}
if (this._processQueue) {
return that._getDeferredState(this._processQueue);
}
};
data.processing = function () {
return !this.jqXHR && this._processQueue && that
._getDeferredState(this._processQueue) === 'pending';
};
data.progress = function () {
return this._progress;
};
data.response = function () {
return this._response;
};
},

jquery.ui.widget.js里面的_trigger函数

this.element.trigger( event, data );

打印event

jQuery.Event {originalEvent: j…y.Event, type: "fileuploadadd", isDefaultPrevented: ƒ, timeStamp: 1561917127348, jQuery111304105261403454039: true, …}currentTarget: input#fileuploaddata: undefineddelegateTarget: input#fileuploaddelegatedEvent: jQuery.Event {originalEvent: Event, type: "change", isDefaultPrevented: ƒ, timeStamp: 33359.854999987874, jQuery111304105261403454039: true, …}handleObj: {type: "fileuploadadd", origType: "fileuploadadd", data: undefined, handler: ƒ, guid: 20, …}isDefaultPrevented: ƒ returnFalse()isTrigger: 3jQuery111304105261403454039: truenamespace: ""namespace_re: nulloriginalEvent: jQuery.Event {type: "add", delegatedEvent: j…y.Event, timeStamp: 1561917127348, jQuery111304105261403454039: true}result: undefinedtarget: input#fileuploadtimeStamp: 1561917127348type: "fileuploadadd"__proto__: Object

trigger后面的代码是

return !( $.isFunction( callback ) &&
callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
event.isDefaultPrevented() );

callback对应下面的add

// The add callback is invoked as soon as files are added to the fileupload
// widget (via file input selection, drag & drop or add API call).
// See the basic file upload widget for more information:
add: function (e, data) {
if (e.isDefaultPrevented()) {
return false;
}
var $this = $(this),
that = $this.data('blueimp-fileupload') ||
$this.data('fileupload'),
options = that.options;
data.context = that._renderUpload(data.files)
.data('data', data)
.addClass('processing');
options.filesContainer[
options.prependFiles ? 'prepend' : 'append'
](data.context);
that._forceReflow(data.context);
that._transition(data.context);
data.process(function () { //这里的process是在_addConvenienceMethods里面定义的
return $this.fileupload('process', data);
}).always(function () {
data.context.each(function (index) {
$(this).find('.size').text(
that._formatFileSize(data.files[index].size)
);
}).removeClass('processing');
that._renderPreviews(data);
}).done(function () {
data.context.find('.start').prop('disabled', false);
if ((that._trigger('added', e, data) !== false) &&
(options.autoUpload || data.autoUpload) &&
data.autoUpload !== false) {
data.submit();
}
}).fail(function () {
if (data.files.error) {
data.context.each(function (index) {
var error = data.files[index].error;
if (error) {
$(this).find('.error').text(error);
}
});
}
});
},

jquery.fileupload-ui.js里面的

 _renderUpload: function (files) {
return this._renderTemplate(
this.options.uploadTemplate, //自己做测试的,这边是null
files
);
},
_renderTemplate: function (func, files) {
if (!func) {
return $(); //自己做测试,这边就返回了
}
var result = func({
files: files,
formatFileSize: this._formatFileSize,
options: this.options
});
if (result instanceof $) {
return result;
}
return $(this.options.templatesContainer).html(result).children();
},
_forceReflow: function (node) {
return $.support.transition && node.length &&
node[0].offsetWidth;
},
_transition: function (node) {
var dfd = $.Deferred();
if ($.support.transition && node.hasClass('fade') && node.is(':visible')) {
node.bind(
$.support.transition.end,
function (e) {
// Make sure we don't respond to other transitions events
// in the container element, e.g. from button elements:
if (e.target === node[0]) {
node.unbind($.support.transition.end);
dfd.resolveWith(node);
}
}
).toggleClass('in');
} else {
node.toggleClass('in');
dfd.resolveWith(node);

}
return dfd;
},
 data.process = function (resolveFunc, rejectFunc) {
if (resolveFunc || rejectFunc) {
data._processQueue = this._processQueue =
(this._processQueue || getPromise([this])).then(
function () {
if (data.errorThrown) {
return $.Deferred()
.rejectWith(that, [data]).promise();
}
return getPromise(arguments);
}
).then(resolveFunc, rejectFunc);
}
return this._processQueue || getPromise([this]);
};

然后跳转jquery.fileupload-ui.js里面

 // Processes the files given as files property of the data parameter,
// returns a Promise object that allows to bind callbacks:
process: function (data) {
var that = this,
options = $.extend({}, this.options, data);
if (options.processQueue && options.processQueue.length) {
this._transformProcessQueue(options);
if (this._processing === 0) {
this._trigger('processstart');
}
$.each(data.files, function (index) {
var opts = index ? $.extend({}, options) : options,
func = function () {
if (data.errorThrown) {
return $.Deferred()
.rejectWith(that, [data]).promise();
}
return that._processFile(opts, data);
};
opts.index = index;
that._processing += 1;
that._processingQueue = that._processingQueue.then(func, func)
.always(function () {
that._processing -= 1;
if (that._processing === 0) {
that._trigger('processstop');
}
});
});
}
return this._processingQueue;
},
// Replaces the settings of each processQueue item that
// are strings starting with an "@", using the remaining
// substring as key for the option map,
// e.g. "@autoUpload" is replaced with options.autoUpload:
_transformProcessQueue: function (options) {
var processQueue = [];
$.each(options.processQueue, function () {
var settings = {},
action = this.action,
prefix = this.prefix === true ? action : this.prefix;
$.each(this, function (key, value) {
if ($.type(value) === 'string' &&
value.charAt(0) === '@') {
settings[key] = options[
value.slice(1) || (prefix ? prefix +
key.charAt(0).toUpperCase() + key.slice(1) : key)
];
} else {
settings[key] = value;
} });
processQueue.push(settings);
});
options.processQueue = processQueue;
},
 processstart: function (e) {
if (e.isDefaultPrevented()) {
return false;
}
$(this).addClass('fileupload-processing');
},

然后是jquery.fileupload-process.js里面的

_processFile: function (data, originalData) {
var that = this,
dfd = $.Deferred().resolveWith(that, [data]),
chain = dfd.promise();
this._trigger('process', null, data);
$.each(data.processQueue, function (i, settings) {
var func = function (data) {
if (originalData.errorThrown) {
return $.Deferred()
.rejectWith(that, [originalData]).promise();
}
return that.processActions[settings.action].call(
that,
data,
settings
);
};
chain = chain.then(func, settings.always && func);
});
chain
.done(function () {
that._trigger('processdone', null, data);
that._trigger('processalways', null, data);
})
.fail(function () {
that._trigger('processfail', null, data);
that._trigger('processalways', null, data);
});
return chain;
},
 // Processes the files given as files property of the data parameter,
// returns a Promise object that allows to bind callbacks:
process: function (data) {
var that = this,
options = $.extend({}, this.options, data);
if (options.processQueue && options.processQueue.length) {
this._transformProcessQueue(options);
if (this._processing === 0) {
this._trigger('processstart');
}
$.each(data.files, function (index) {
var opts = index ? $.extend({}, options) : options,
func = function () {
if (data.errorThrown) {
return $.Deferred()
.rejectWith(that, [data]).promise();
}
return that._processFile(opts, data);
};
opts.index = index;
that._processing += 1;
that._processingQueue = that._processingQueue.then(func, func)
.always(function () {
that._processing -= 1;
if (that._processing === 0) {
that._trigger('processstop');
}
});
});
}
return this._processingQueue;
},

结论

绑定事件的时候依赖于this.options.filesContainer,这玩意不存在于jquery.fileupload.js里面

 _initEventHandlers: function () {
this._super(); var handlers = {};
handlers[this.options.uploadImageEditorPreviewSelector] = this._previewHandler.bind(this);
console.log(`filesContainer = ${this.options.filesContainer}`);
this._on(this.options.filesContainer, handlers);
},

而filesContainer在jquery.fileupload-ui.js中

 // The container for the list of files. If undefined, it is set to
// an element with class "files" inside of the widget element:
filesContainer: undefined, _initFilesContainer: function () {
var options = this.options;
if (options.filesContainer === undefined) {
options.filesContainer = this.element.find('.files');
} else if (!(options.filesContainer instanceof $)) {
options.filesContainer = $(options.filesContainer);
}
},

因为basic.html没有引用jquery.fileupload-ui.js,所以导致事件绑定失败。

顺便打印一下this.element

console.log(`filesContainer = ${this.options.filesContainer}`);
console.log(this.element);

自己手动复制函数,然后在_initEventHandlers里面调用

  _initFilesContainer: function () {
var options = this.options;
if (options.filesContainer === undefined) {
options.filesContainer = this.element.find('.files');
} else if (!(options.filesContainer instanceof $)) {
options.filesContainer = $(options.filesContainer);
}
},
_initEventHandlers: function () {
this._super();
this._initFilesContainer();
var handlers = {};
handlers[this.options.uploadImageEditorPreviewSelector] = this._previewHandler.bind(this);
this._on(this.options.filesContainer, handlers);
},

页面加载后,进行查询

$('#fileupload').fileupload('option', 'filesContainer')

在还有jquery.fileupload-ui.js里面还有关于uploadTemplateID的设置

options: {
// By default, files added to the widget are uploaded as soon
// as the user clicks on the start buttons. To enable automatic
// uploads, set the following option to true:
autoUpload: false,
// The ID of the upload template:
uploadTemplateId: 'template-upload',
// The ID of the download template:
downloadTemplateId: 'template-download',

jQuery file upload cropper的 click .preview事件没有绑定成功的更多相关文章

  1. jQuery file upload cropper的流程

    https://tkvw.github.io/jQuery-File-Upload/basic-plus-editor.html 最开始初始化jquery.ui.widget.js中的factory( ...

  2. jQuery File Upload

    jQuery File Upload介绍.............................................. 2 实现基本原理......................... ...

  3. jQuery File Upload 单页面多实例的实现

    jQuery File Upload 的 GitHub 地址:https://github.com/blueimp/jQuery-File-Upload 插件描述:jQuery File Upload ...

  4. jQuery File Upload blueimp with struts2 简单试用

    Official Site的话随便搜索就可以去了 另外新版PHP似乎都有问题  虽然图片都可以上传  但是response报错  我下载的是8.8.7木有问题   但是8.8.7版本结合修改main. ...

  5. 定制jQuery File Upload为微博式单文件上传

    日志未经声明,均为AlloVince原创.版权采用『 知识共享署名-非商业性使用 2.5 许可协议』进行许可. jQuery File Upload是一个非常优秀的上传组件,主要使用了XHR作为上传方 ...

  6. jquery file upload示例

    原文链接:http://blog.csdn.net/qq_37936542/article/details/79258158 jquery file upload是一款实用的上传文件插件,项目中刚好用 ...

  7. jQuery File Upload的使用

    jQuery File Upload 是一个Jquery文件上传组件,支持多文件上传.取消.删除,上传前缩略图预览.列表显示图片大小,支持上传进度条显示等,以下就介绍一下该插件的简单使用 1.需要加载 ...

  8. jQuery file upload callback options

    autoUpload By default, files added to the widget are uploaded as soon as the user clicks on the star ...

  9. jQuery File Upload done函数没有返回

    最近在使用jQuery File Upload 上传图片时发现一个问题,发现done函数没有callback,经过一番折腾,找到问题原因,是由于dataType: ‘json’造成的,改为autoUp ...

随机推荐

  1. linux:文件/目录权限设置

    一.权限修改命令:     chmod [OPTION]... MODE[,MODE]... FILE...二.文件/目录MODE指定方式: 1).八进制(r=4,w=2,x=1) [root@pin ...

  2. 使用filebeat收集日志传输到redis的各种效果展示

    0 环境 Linux主机,cengtos7系统 安装有openresty软件,用来访问生成日志信息 1.15.8版本 安装有filebeat软件,用来收集openresty的日志 7.3版本 安装有r ...

  3. Jade学习(五)之命令编译执行jade

    首先全局安装jade,我们就可以使用jade 命令了! jade index.jade // 解析后会在文件夹中新生成一个压缩代码后的index.html 如果我们不想生成的index.html文件进 ...

  4. vue项目1-pizza点餐系统3-路由知识点补充

    1.可以通过tag修改router-link的默认标签 <!--router-link标签默认是a标签,tag标签可以修改默认标签 --> <li><router-lin ...

  5. springboot项目抓数据后优化配置及四个补充

    昨天搞了一个抓取某某平台信息的抓取功能,其中有一个地址url,昨天是写死的,之前也进行配置过,印象有些模糊,今天想配置一下,在properties文件中,由此引发了下面的一系列总结操作: 1.原始模式 ...

  6. Js不用for,forEach,map等循环实现九九乘法表

    var str='';function mt(p,n){ if(p<10){ if (n<=p){ str += n+'*'+p+'='+p*n+'\t'; n++; mt(p,n); } ...

  7. centos7安装部署jumpserver

    一.系统环境准备1.查看系统版本 # cat /etc/redhat-release // 查看系统版本 CentOS Linux release (Core) # uname -a // 查看系统信 ...

  8. KVM虚拟化简介及安装

    kvm是基于图形化的linux操作的 安装图形化界面的知识点: 磁盘空间有两个词: 精简置备:我先在我系统里面去声明我要一个50G的空间,但是呢,我不会把50G都分给你,你用多少,我分给你多少,但是做 ...

  9. Hive的安装搭建(三)

    03 Hive的安装搭建 Hive可以从源码中编译安装,也可以直接使用官网下载的安装包,在此处我们选择安装包解压安装的方式. Hive中最最重要的角色就是metastore 因此按照metastore ...

  10. 前端matrix矩阵的变化

    css3 transform中的matrix矩阵   CSS3中的矩阵CSS3中的矩阵指的是一个方法,书写为matrix()和matrix3d(),前者是元素2D平面的移动变换(transform), ...