测试

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

  1. 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;
}
},

  1. // Adds convenience methods to the data callback argument:
  2. _addConvenienceMethods: function (e, data) {
  3. var that = this,
  4. getPromise = function (args) {
  5. return $.Deferred().resolveWith(that, args).promise();
  6. };
  7. data.process = function (resolveFunc, rejectFunc) {
  8. if (resolveFunc || rejectFunc) {
  9. data._processQueue = this._processQueue =
  10. (this._processQueue || getPromise([this])).then(
  11. function () {
  12. if (data.errorThrown) {
  13. return $.Deferred()
  14. .rejectWith(that, [data]).promise();
  15. }
  16. return getPromise(arguments);
  17. }
  18. ).then(resolveFunc, rejectFunc);
  19. }
  20. return this._processQueue || getPromise([this]);
  21. };
  22. data.submit = function () {
  23. if (this.state() !== 'pending') {
  24. data.jqXHR = this.jqXHR =
  25. (that._trigger(
  26. 'submit',
  27. $.Event('submit', {delegatedEvent: e}),
  28. this
  29. ) !== false) && that._onSend(e, this);
  30. }
  31. return this.jqXHR || that._getXHRPromise();
  32. };
  33. data.abort = function () {
  34. if (this.jqXHR) {
  35. return this.jqXHR.abort();
  36. }
  37. this.errorThrown = 'abort';
  38. that._trigger('fail', null, this);
  39. return that._getXHRPromise(false);
  40. };
  41. data.state = function () {
  42. if (this.jqXHR) {
  43. return that._getDeferredState(this.jqXHR);
  44. }
  45. if (this._processQueue) {
  46. return that._getDeferredState(this._processQueue);
  47. }
  48. };
  49. data.processing = function () {
  50. return !this.jqXHR && this._processQueue && that
  51. ._getDeferredState(this._processQueue) === 'pending';
  52. };
  53. data.progress = function () {
  54. return this._progress;
  55. };
  56. data.response = function () {
  57. return this._response;
  58. };
  59. },

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

  1. // The add callback is invoked as soon as files are added to the fileupload
  2. // widget (via file input selection, drag & drop or add API call).
  3. // See the basic file upload widget for more information:
  4. add: function (e, data) {
  5. if (e.isDefaultPrevented()) {
  6. return false;
  7. }
  8. var $this = $(this),
  9. that = $this.data('blueimp-fileupload') ||
  10. $this.data('fileupload'),
  11. options = that.options;
  12. data.context = that._renderUpload(data.files)
  13. .data('data', data)
  14. .addClass('processing');
  15. options.filesContainer[
  16. options.prependFiles ? 'prepend' : 'append'
  17. ](data.context);
  18. that._forceReflow(data.context);
  19. that._transition(data.context);
  20. data.process(function () { //这里的process是在_addConvenienceMethods里面定义的
  21. return $this.fileupload('process', data);
  22. }).always(function () {
  23. data.context.each(function (index) {
  24. $(this).find('.size').text(
  25. that._formatFileSize(data.files[index].size)
  26. );
  27. }).removeClass('processing');
  28. that._renderPreviews(data);
  29. }).done(function () {
  30. data.context.find('.start').prop('disabled', false);
  31. if ((that._trigger('added', e, data) !== false) &&
  32. (options.autoUpload || data.autoUpload) &&
  33. data.autoUpload !== false) {
  34. data.submit();
  35. }
  36. }).fail(function () {
  37. if (data.files.error) {
  38. data.context.each(function (index) {
  39. var error = data.files[index].error;
  40. if (error) {
  41. $(this).find('.error').text(error);
  42. }
  43. });
  44. }
  45. });
  46. },

jquery.fileupload-ui.js里面的

  1. _renderUpload: function (files) {
  2. return this._renderTemplate(
  3. this.options.uploadTemplate, //自己做测试的,这边是null
  4. files
  5. );
  6. },
  1. _renderTemplate: function (func, files) {
  2. if (!func) {
  3. return $(); //自己做测试,这边就返回了
  4. }
  5. var result = func({
  6. files: files,
  7. formatFileSize: this._formatFileSize,
  8. options: this.options
  9. });
  10. if (result instanceof $) {
  11. return result;
  12. }
  13. return $(this.options.templatesContainer).html(result).children();
  14. },
  1. _forceReflow: function (node) {
  2. return $.support.transition && node.length &&
  3. node[0].offsetWidth;
  4. },
  1. _transition: function (node) {
  2. var dfd = $.Deferred();
  3. if ($.support.transition && node.hasClass('fade') && node.is(':visible')) {
  4. node.bind(
  5. $.support.transition.end,
  6. function (e) {
  7. // Make sure we don't respond to other transitions events
  8. // in the container element, e.g. from button elements:
  9. if (e.target === node[0]) {
  10. node.unbind($.support.transition.end);
  11. dfd.resolveWith(node);
  12. }
  13. }
  14. ).toggleClass('in');
  15. } else {
  16. node.toggleClass('in');
  17. dfd.resolveWith(node);
  18. }
  19. return dfd;
  20. },
  1. data.process = function (resolveFunc, rejectFunc) {
  2. if (resolveFunc || rejectFunc) {
  3. data._processQueue = this._processQueue =
  4. (this._processQueue || getPromise([this])).then(
  5. function () {
  6. if (data.errorThrown) {
  7. return $.Deferred()
  8. .rejectWith(that, [data]).promise();
  9. }
  10. return getPromise(arguments);
  11. }
  12. ).then(resolveFunc, rejectFunc);
  13. }
  14. return this._processQueue || getPromise([this]);
  15. };

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

  1. // Processes the files given as files property of the data parameter,
  2. // returns a Promise object that allows to bind callbacks:
  3. process: function (data) {
  4. var that = this,
  5. options = $.extend({}, this.options, data);
  6. if (options.processQueue && options.processQueue.length) {
  7. this._transformProcessQueue(options);
  8. if (this._processing === 0) {
  9. this._trigger('processstart');
  10. }
  11. $.each(data.files, function (index) {
  12. var opts = index ? $.extend({}, options) : options,
  13. func = function () {
  14. if (data.errorThrown) {
  15. return $.Deferred()
  16. .rejectWith(that, [data]).promise();
  17. }
  18. return that._processFile(opts, data);
  19. };
  20. opts.index = index;
  21. that._processing += 1;
  22. that._processingQueue = that._processingQueue.then(func, func)
  23. .always(function () {
  24. that._processing -= 1;
  25. if (that._processing === 0) {
  26. that._trigger('processstop');
  27. }
  28. });
  29. });
  30. }
  31. return this._processingQueue;
  32. },
  1. // Replaces the settings of each processQueue item that
  2. // are strings starting with an "@", using the remaining
  3. // substring as key for the option map,
  4. // e.g. "@autoUpload" is replaced with options.autoUpload:
  5. _transformProcessQueue: function (options) {
  6. var processQueue = [];
  7. $.each(options.processQueue, function () {
  8. var settings = {},
  9. action = this.action,
  10. prefix = this.prefix === true ? action : this.prefix;
  11. $.each(this, function (key, value) {
  12. if ($.type(value) === 'string' &&
  13. value.charAt(0) === '@') {
  14. settings[key] = options[
  15. value.slice(1) || (prefix ? prefix +
  16. key.charAt(0).toUpperCase() + key.slice(1) : key)
  17. ];
  18. } else {
  19. settings[key] = value;
  20. }
  21.  
  22. });
  23. processQueue.push(settings);
  24. });
  25. options.processQueue = processQueue;
  26. },
  1. processstart: function (e) {
  2. if (e.isDefaultPrevented()) {
  3. return false;
  4. }
  5. $(this).addClass('fileupload-processing');
  6. },

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

  1. _processFile: function (data, originalData) {
  2. var that = this,
  3. dfd = $.Deferred().resolveWith(that, [data]),
  4. chain = dfd.promise();
  5. this._trigger('process', null, data);
  6. $.each(data.processQueue, function (i, settings) {
  7. var func = function (data) {
  8. if (originalData.errorThrown) {
  9. return $.Deferred()
  10. .rejectWith(that, [originalData]).promise();
  11. }
  12. return that.processActions[settings.action].call(
  13. that,
  14. data,
  15. settings
  16. );
  17. };
  18. chain = chain.then(func, settings.always && func);
  19. });
  20. chain
  21. .done(function () {
  22. that._trigger('processdone', null, data);
  23. that._trigger('processalways', null, data);
  24. })
  25. .fail(function () {
  26. that._trigger('processfail', null, data);
  27. that._trigger('processalways', null, data);
  28. });
  29. return chain;
  30. },
  1. // Processes the files given as files property of the data parameter,
  2. // returns a Promise object that allows to bind callbacks:
  3. process: function (data) {
  4. var that = this,
  5. options = $.extend({}, this.options, data);
  6. if (options.processQueue && options.processQueue.length) {
  7. this._transformProcessQueue(options);
  8. if (this._processing === 0) {
  9. this._trigger('processstart');
  10. }
  11. $.each(data.files, function (index) {
  12. var opts = index ? $.extend({}, options) : options,
  13. func = function () {
  14. if (data.errorThrown) {
  15. return $.Deferred()
  16. .rejectWith(that, [data]).promise();
  17. }
  18. return that._processFile(opts, data);
  19. };
  20. opts.index = index;
  21. that._processing += 1;
  22. that._processingQueue = that._processingQueue.then(func, func)
  23. .always(function () {
  24. that._processing -= 1;
  25. if (that._processing === 0) {
  26. that._trigger('processstop');
  27. }
  28. });
  29. });
  30. }
  31. return this._processingQueue;
  32. },

结论

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

  1. _initEventHandlers: function () {
  2. this._super();
  3.  
  4. var handlers = {};
  5. handlers[this.options.uploadImageEditorPreviewSelector] = this._previewHandler.bind(this);
  6. console.log(`filesContainer = ${this.options.filesContainer}`);
  7. this._on(this.options.filesContainer, handlers);
  8. },

而filesContainer在jquery.fileupload-ui.js中

  1. // The container for the list of files. If undefined, it is set to
  2. // an element with class "files" inside of the widget element:
  3. filesContainer: undefined,
  4.  
  5. _initFilesContainer: function () {
  6. var options = this.options;
  7. if (options.filesContainer === undefined) {
  8. options.filesContainer = this.element.find('.files');
  9. } else if (!(options.filesContainer instanceof $)) {
  10. options.filesContainer = $(options.filesContainer);
  11. }
  12. },

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

顺便打印一下this.element

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

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

  1. _initFilesContainer: function () {
  2. var options = this.options;
  3. if (options.filesContainer === undefined) {
  4. options.filesContainer = this.element.find('.files');
  5. } else if (!(options.filesContainer instanceof $)) {
  6. options.filesContainer = $(options.filesContainer);
  7. }
  8. },
  9. _initEventHandlers: function () {
  10. this._super();
  11. this._initFilesContainer();
  12. var handlers = {};
  13. handlers[this.options.uploadImageEditorPreviewSelector] = this._previewHandler.bind(this);
  14. this._on(this.options.filesContainer, handlers);
  15. },

页面加载后,进行查询

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

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

  1. 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. Homebrew学习(六)之替换及重置homebrew、Homebred Core、Homebrew cask默认源

    替换及重置homebrew默认源 中科大源 替换官方源: // 替换brew.git: cd "$(brew --repo)" git remote set-url origin ...

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

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

  3. vue-cli常用插件安装教程

    1.安装sass npm i sass-loader node-sass --save-dev 2.安装stylus cnpm install stylus --save-dev cnpm insta ...

  4. TS学习

    随着vue3.0的即将到来,是时候学习一下TS了 简介:TypeScript是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类 ...

  5. Fuel9.0部署

    一.安装环境(准备工作): 1. 所需物理主机的要求如下 内存:8GB+,推荐16GB:(少于8GB的就免谈了) 磁盘:500GB+: 物理机OS:ubuntu-desktop-amd64 14.04 ...

  6. SQL Server设置启动存储过程

    --设置开关 启动程序自动运行存储过程必须启动该命令 sp_configure "show advanced options",1; go reconfigure; go --设置 ...

  7. Java学习03-进制学习

    计算机中是以二进制来进行数据传递的,二进制分为二进制.八进制.十进制.十六进制 而他们之间如何进行转换呢,二进制作为元,其他进制都是经二进制进行换算的,所以无论什么进制之间的转换都是先转换为二进制,再 ...

  8. 生成树计数及应用 Matrix-Tree

    例:给定一个图,图上每条边是红色或蓝色 求恰好有K条红边的生成树的个数,N<=50. Matrix-Tree定理 对于限制条件可以利用多项式,把红边边权设为X,蓝边边权设为1. 最后求行列式得到 ...

  9. creat-react-app生成的项目默认端口号是3000,如何更改?

    从项目的 package.json 文件中可以看到,npm start即scripts start.js,因此我们找到scripts/start.js ,部分代码如下: 找到 DEFAULT_PORT ...

  10. 描述GPT是什么?

    介绍: 全球唯一标识分区表(GUID Partition Table,缩写:GPT)是一个实体硬盘的分区表的结构布局的标准.它是可扩展固件接口(UEFI)标准(被Inter用于代替个人计算机的BIOS ...