- 浏览: 3292042 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (567)
- Web前端-html/表单 (19)
- Web前端-CSS (24)
- Web前端-CSS框架 (4)
- Web前端-JS语言核心 (50)
- Web前端-JS客户端 (26)
- nodejs生态+grunt (10)
- seajs和requirejs (9)
- backbone等框架 (7)
- 模板基础 (7)
- Web前端-deps(不改动) (6)
- Web前端-component (10)
- Web前端-jquery-plugin (13)
- 浏览器兼容性 (6)
- Web前端-使用jQuery (25)
- Web前端-使用jqueryui (6)
- Web前端-性能优化 (3)
- Web协议-HTTP (6)
- ExtJS (13)
- PHP (22)
- PHP面向对象 (4)
- PHP扩展-SOAP (6)
- PHP扩展-curl (4)
- PHP与HTML(导出) (5)
- PHP扩展-综合 (7)
- mysql基础应用 (18)
- 技术心情 (18)
- 算法和面试题 (17)
- 工具(开发)使用 (36)
- memcached原理 (2)
- session和cookie (4)
- UML (2)
- Web前端_FusionCharts (5)
- Web前端_Flex (4)
- Web前端_JSP (3)
- JavaSE (10)
- JavaEE (4)
- tomcat (2)
- Servlet开发 (3)
- Spring开发 (1)
- REST相关 (2)
- 大访问量、高并发 (2)
- 网络编程 (1)
- YII (21)
- linux命令和内核 (12)
- yii与数据库 (10)
- yii与表单 (12)
- yii view层 (1)
- perl (7)
- yii扩展 (7)
- shell (4)
- photoshop (7)
- 视觉设计 (2)
- 我关注的名人在路上 (4)
- 1-自学能力 (1)
- 2-人际沟通能力 (3)
- 3-职业规划能力 (7)
- 4-项目管理能力 (2)
- python (3)
- django (4)
- Mysql高级应用 (6)
- prototype.js (4)
- Web系统安全 (1)
- Web前端-mobile (2)
- egret (6)
- jQuery源码分析 (5)
- fis (4)
最新评论
-
yzq21056563:
感谢作者分享~请教下,http://www.lisa33xia ...
CSS基础:text-overflow:ellipsis溢出文本 -
u012206458:
$.ajax的error,complete,success方法 -
DEMONU:
谢谢,虽然不能给你赞助,但是要给你顶
mysql中key 、primary key 、unique key 与index区别 -
njupt_tolmes:
阿凡达阿凡达阿凡达阿凡达阿凡达阿凡达阿凡达阿凡达阿凡达阿滕庆亚 ...
CSS基础:text-overflow:ellipsis溢出文本 -
zenmshuo:
用过SpreadJS,也包含数据可视化的图表
推荐几个web中常用js图表插件
作者:zccst
2014-12-04
重复提交时的bug
(1)除file字段外的其他字段多次重复添加时出现重复。
需要在添加时先检查是否已经添加过,如果添加过就更新,没添加过再append。
(2)file字段第二次添加时filename为空。
2014-11-14
效果图:
优点:多浏览器统一样式。(原生input type="file"在不同浏览器下表现不一致,对于很多系统这是不能接受的)
html:
js:上传文件初始化
js:上传文件提交
需要后端配合的是:
content-type:text/html。不能是text/javascript,踩过的坑坑,深深的痛。
接下来是组件分析
简单说一下实现原理,通过用户在初始化中填入的设置,默认创建一个透明的form表单和iframe。其中form的target设置为iframe的name,目的是为了跳转。巧妙的是该表单的宽高和看得见的上传按钮宽高完全一致,但zIndex高10(自己设置的)
用户点击按钮时,实际上是在点击表单的input输入框。而负责样式的a标签则没有任何事件。
为透明度为0的input输入框添加了change事件,用户一旦选择文件,则会触发该事件。可以做的事情,比如校验,将文件名写入右侧的span,让用户看上去选择了一个文件。
提交:分两种情况,IE和非IE。
如果是非IE,则使用$.ajax上传,同时设置一个xhr,还可以查看上传进度。
如果是IE,则使用form+iframe方式,并且注册iframe的onload监听事件,服务器端将返回结果放置到iframe中后,onload监听事件需要做的事情是:拿到后端返回的数据,做判断,然后传给setting里注册的回调函数success或error。
里面涉及好几个知识点,比如:
1,FileList
2,formData
3,取iframe的值
var doc = self.iframe[0].contentDocument ? self.iframe[0].contentDocument : self.iframe[0].contentWindow.document;
var str = doc.body.innerHTML;
为了方便看,附两张图:
一个是settings
一个是Uploader对象在setup时的this
一个是Uploader对象在submit时的this(区别是多了_files)
uploader.js组件
如果您觉得本文的内容对您的学习有所帮助,您可以微信:
2014-12-04
重复提交时的bug
(1)除file字段外的其他字段多次重复添加时出现重复。
需要在添加时先检查是否已经添加过,如果添加过就更新,没添加过再append。
(2)file字段第二次添加时filename为空。
2014-11-14
效果图:
优点:多浏览器统一样式。(原生input type="file"在不同浏览器下表现不一致,对于很多系统这是不能接受的)
html:
<span class="button_box1"><a href="javascript:;" name="file" id="file" style=""><span>选择文件</span></a></span> <span class="batch-upload-filename"></span>
js:上传文件初始化
//初始化文件上传组件 initUploader:function(){ var _this = this; var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; var splitPath = function(filename) { return splitPathRe.exec(filename).slice(1); }; //Excel上传控件 this.batch_uploader = new Uploader({ trigger: '#file', name: 'file', action: CREATE_EXCELFEED_URL, accept: 'application/vnd.ms-excel', data: {}, dataType:'json', multiple: false }).change(function(files) { for (var i = 0; i < files.length; i++) { var fileType = splitPath(files[i].name)[3]; if (fileType !== ".xls") { alert("文件格式错误, 请上传.xls格式文件!"); } else { $('.batch-upload-filename').html(files[i].name); } } }).success(function(response) { /**/ var res; if($.type(response) === "string"){ // IE浏览器走这个逻辑 res = $.parseJSON(response); }else if($.type(response) === "object"){//FF,Chrome走这个逻辑 res = response; }else{//奇怪的第三种情况 res = $.parseJSON($(response).text()); } /*旧实现方式 if(/msie/.test(navigator.userAgent.toLowerCase())) { if($.type(response) === "string"){ res = $.parseJSON(response); }else{ res = $.parseJSON($(response).text()); } } else { console.log(response, $.type(response)); }*/ if (res.flag == 0) { //成功后刷新 _this.createSuccessCallback(); } else { var msg = res.msg || []; alert("上传失败,原因:"+ (msg.length !== 0 ? msg.join('\r\n') : '未知。') ); } //如果选择文件立即上传时 //_this.$el.find('.batch-upload-filename').html(' 未选择文件'); }).error(function(file) { alert("上传"+file+"失败,请重试。"); }); },
js:上传文件提交
if(this.batch_uploader._uploaders[0]._files) { this.$el.find(".errormsg").hide(); this.batch_uploader._uploaders[0].form.append(_this.createInputs(params)); this.batch_uploader.submit(); } else { this.$el.find(".errormsg").html("请先选择要上传的文件,再提交!").show(); return false; }
需要后端配合的是:
content-type:text/html。不能是text/javascript,踩过的坑坑,深深的痛。
接下来是组件分析
简单说一下实现原理,通过用户在初始化中填入的设置,默认创建一个透明的form表单和iframe。其中form的target设置为iframe的name,目的是为了跳转。巧妙的是该表单的宽高和看得见的上传按钮宽高完全一致,但zIndex高10(自己设置的)
用户点击按钮时,实际上是在点击表单的input输入框。而负责样式的a标签则没有任何事件。
为透明度为0的input输入框添加了change事件,用户一旦选择文件,则会触发该事件。可以做的事情,比如校验,将文件名写入右侧的span,让用户看上去选择了一个文件。
提交:分两种情况,IE和非IE。
如果是非IE,则使用$.ajax上传,同时设置一个xhr,还可以查看上传进度。
如果是IE,则使用form+iframe方式,并且注册iframe的onload监听事件,服务器端将返回结果放置到iframe中后,onload监听事件需要做的事情是:拿到后端返回的数据,做判断,然后传给setting里注册的回调函数success或error。
里面涉及好几个知识点,比如:
1,FileList
2,formData
3,取iframe的值
var doc = self.iframe[0].contentDocument ? self.iframe[0].contentDocument : self.iframe[0].contentWindow.document;
var str = doc.body.innerHTML;
为了方便看,附两张图:
一个是settings
一个是Uploader对象在setup时的this
一个是Uploader对象在submit时的this(区别是多了_files)
uploader.js组件
define(function(require, exports, module){ //var $ = require('jquery'); var iframeCount = 0; function Uploader(options) { if (!(this instanceof Uploader)) { return new Uploader(options); } if (isString(options)) { options = {trigger: options}; } var settings = { trigger: null, name: null, action: null, data: null, accept: null, change: null, error: null, multiple: true, success: null }; if (options) { $.extend(settings, options); } var $trigger = $(settings.trigger); settings.action = settings.action || $trigger.data('action') || '/upload'; settings.name = settings.name || $trigger.attr('name') || $trigger.data('name') || 'file'; settings.data = settings.data || parse($trigger.data('data')); settings.accept = settings.accept || $trigger.data('accept'); settings.success = settings.success || $trigger.data('success'); this.settings = settings; this.setup(); this.bind(); } // initialize // create input, form, iframe Uploader.prototype.setup = function() { this.form = $( '<form class="earth-upload" method="post" enctype="multipart/form-data"' + 'target="" action="' + this.settings.action + '"></form>' ); this.iframe = newIframe();//<iframe name="iframe-uploader-0" style="display: none;"> //<form class="earth-upload" action="/feed/createExcelFeed.action" target="iframe-uploader-0" enctype="multipart/form-data" method="post"></form> this.form.attr('target', this.iframe.attr('name')); var data = this.settings.data; this.form.append(createInputs(data)); if (window.FormData) { //<input value="formdata" name="_uploader_" type="hidden"> this.form.append(createInputs({'_uploader_': 'formdata'})); } else { //<input value="iframe" name="_uploader_" type="hidden"> this.form.append(createInputs({'_uploader_': 'iframe'})); } var input = document.createElement('input'); input.type = 'file'; input.name = this.settings.name; if (this.settings.accept) { input.accept = this.settings.accept; } if (this.settings.multiple) { input.multiple = true; input.setAttribute('multiple', 'multiple'); } this.input = $(input); //<input type="file" name="file" accept="application/vnd.ms-excel"> var $trigger = $(this.settings.trigger); this.input.attr('hidefocus', true).css({ position: 'absolute', top: 0, right: 0, opacity: 0, outline: 0, cursor: 'pointer', height: $trigger.outerHeight(), fontSize: Math.max(64, $trigger.outerHeight() * 5) }); //<input type="file" name="file" accept="application/vnd.ms-excel" hidefocus="true" style="position: absolute; top: 0px; right: 0px; opacity: 0; outline: 0px none; cursor: pointer; height: 30px; font-size: 150px;"> this.form.append(this.input); this.form.css({ position: 'absolute', top: $trigger.offset().top, left: $trigger.offset().left, overflow: 'hidden', width: $trigger.outerWidth(), height: $trigger.outerHeight(), zIndex: findzIndex($trigger) + 10 }).appendTo('body'); /* * <form action="/feed/createExcelFeed.action" target="iframe-uploader-0" enctype="multipart/form-data" method="post" class="earth-upload" style="position: absolute; top: 177px; left: 371px; overflow: hidden; width: 80px; height: 30px; z-index: 1037;"> * <input type="hidden" name="_uploader_" value="formdata"> * <input type="file" name="file" accept="application/vnd.ms-excel" hidefocus="true" style="position: absolute; top: 0px; right: 0px; opacity: 0; outline: 0px none; cursor: pointer; height: 30px; font-size: 150px;"> * </form> * */ return this; }; // bind events Uploader.prototype.bind = function() { var self = this; var $trigger = $(self.settings.trigger); $trigger.mouseenter(function() { self.form.css({ top: $trigger.offset().top, left: $trigger.offset().left, width: $trigger.outerWidth(), height: $trigger.outerHeight() }); }); self.bindInput(); }; Uploader.prototype.bindInput = function() { var self = this; self.input.change(function(e) { // ie9 don't support FileList Object // http://stackoverflow.com/questions/12830058/ie8-input-type-file-get-files self._files = this.files || [{ name: e.target.value }];// files 是一个 FileList 对象(类似于NodeList对象) var file = self.input.val(); if (self.settings.change) { self.settings.change.call(self, self._files); } else if (file) { return self.submit(); } }); }; // handle submit event // prepare for submiting form Uploader.prototype.submit = function() { var self = this; if (window.FormData && self._files) { // build a FormData var form = new FormData(self.form.get(0)); // use FormData to upload form.append(self.settings.name, self._files); var optionXhr; if (self.settings.progress) { // fix the progress target file var files = self._files; optionXhr = function() { var xhr = $.ajaxSettings.xhr(); if (xhr.upload) { xhr.upload.addEventListener('progress', function(event) { var percent = 0; var position = event.loaded || event.position; /*event.position is deprecated*/ var total = event.total; if (event.lengthComputable) { percent = Math.ceil(position / total * 100); } self.settings.progress(event, position, total, percent, files); }, false); } return xhr; }; } $.ajax({ url: self.settings.action, type: 'post', processData: false, contentType: false, data: form, xhr: optionXhr, context: this, dataType:self.settings.dataType, success: self.settings.success, error: self.settings.error }); return this; } else { // iframe upload self.iframe = newIframe(); self.form.attr('target', self.iframe.attr('name')); $('body').append(self.iframe); self.iframe.one('load', function() { var doc = self.iframe[0].contentDocument ? self.iframe[0].contentDocument : self.iframe[0].contentWindow.document; var str = doc.body.innerHTML; if(str){ if (self.settings.success) { self.settings.success(str); } }else{ if (self.settings.error) { self.settings.error(self.input.val()); } } /*实现方法二 // https://github.com/blueimp/jQuery-File-Upload/blob/9.5.6/js/jquery.iframe-transport.js#L102 // Fix for IE endless progress bar activity bug // (happens on form submits to iframe targets): $('<iframe src="javascript:false;"></iframe>') .appendTo(self.form) .remove(); var response = $(this).contents().find('body').html(); $(this).remove(); if (!response) { if (self.settings.error) { self.settings.error(self.input.val()); } } else { if (self.settings.success) { self.settings.success(response); } }*/ }); self.form.submit(); } return this; }; Uploader.prototype.refreshInput = function() { //replace the input element, or the same file can not to be uploaded var newInput = this.input.clone(); this.input.before(newInput); this.input.off('change'); this.input.remove(); this.input = newInput; this.bindInput(); }; // handle change event // when value in file input changed Uploader.prototype.change = function(callback) { if (!callback) { return this; } this.settings.change = callback; return this; }; // handle when upload success Uploader.prototype.success = function(callback) { var me = this; this.settings.success = function(response) { me.refreshInput(); if (callback) { callback(response); } }; return this; }; // handle when upload success Uploader.prototype.error = function(callback) { var me = this; this.settings.error = function(response) { if (callback) { me.refreshInput(); callback(response); } }; return this; }; // enable Uploader.prototype.enable = function(){ this.input.prop('disabled', false); this.input.css('cursor', 'pointer'); }; // disable Uploader.prototype.disable = function(){ this.input.prop('disabled', true); this.input.css('cursor', 'not-allowed'); }; // Helpers // ------------- function isString(val) { return Object.prototype.toString.call(val) === '[object String]'; } function createInputs(data) { if (!data) return []; var inputs = [], i; for (var name in data) { i = document.createElement('input'); i.type = 'hidden'; i.name = name; i.value = data[name]; inputs.push(i); } return inputs; } function parse(str) { if (!str) return {}; var ret = {}; var pairs = str.split('&'); var unescape = function(s) { return decodeURIComponent(s.replace(/\+/g, ' ')); }; for (var i = 0; i < pairs.length; i++) { var pair = pairs[i].split('='); var key = unescape(pair[0]); var val = unescape(pair[1]); ret[key] = val; } return ret; } function findzIndex($node) { var parents = $node.parentsUntil('body'); var zIndex = 0; for (var i = 0; i < parents.length; i++) { var item = parents.eq(i); if (item.css('position') !== 'static') { zIndex = parseInt(item.css('zIndex'), 10) || zIndex; } } return zIndex; } function newIframe() { var iframeName = 'iframe-uploader-' + iframeCount; var iframe = $('<iframe src="" id="' + iframeName + '" name="' + iframeName + '"></iframe>').hide(); iframeCount += 1; return iframe; } function MultipleUploader(options) { if (!(this instanceof MultipleUploader)) { return new MultipleUploader(options); } if (isString(options)) { options = {trigger: options}; } var $trigger = $(options.trigger); var uploaders = []; $trigger.each(function(i, item) { options.trigger = item; uploaders.push(new Uploader(options)); }); this._uploaders = uploaders; } MultipleUploader.prototype.submit = function() { $.each(this._uploaders, function(i, item) { item.submit(); }); return this; }; MultipleUploader.prototype.change = function(callback) { $.each(this._uploaders, function(i, item) { item.change(callback); }); return this; }; MultipleUploader.prototype.success = function(callback) { $.each(this._uploaders, function(i, item) { item.success(callback); }); return this; }; MultipleUploader.prototype.error = function(callback) { $.each(this._uploaders, function(i, item) { item.error(callback); }); return this; }; MultipleUploader.prototype.enable = function (){ $.each(this._uploaders, function (i, item){ item.enable(); }); return this; }; MultipleUploader.prototype.disable = function (){ $.each(this._uploaders, function (i, item){ item.disable(); }); return this; }; MultipleUploader.Uploader = Uploader; module.exports = MultipleUploader; });
如果您觉得本文的内容对您的学习有所帮助,您可以微信:
发表评论
-
基于jscal2单日历与双日历控件的实现
2014-08-27 18:51 1484作者:zccst 由单日历改为双日历,整整花了1.5天的实现 ... -
自己写插件的开始
2014-07-25 18:06 596作者:zccst 很久以前就会使用别人写好的插件了,大概是2 ... -
图片轮播(自己实现)
2014-05-27 22:27 1676作者:zccst 2014-09-21 图片轮播的思路是: ... -
插件实现原理-自己总结
2012-10-31 19:05 1215作者:zccst /*file1 ** gms.j ... -
图片轮播(多种实现)
2012-05-13 12:57 1283作者:zccst 图片轮播有很多种形式,且大多可复用性很高。 ... -
二级菜单(插件网址收藏)
2012-05-01 16:53 964作者:zccst 较好的连接地址收藏: 1,阿里西西 批注 ... -
二级菜单(两个源代码)
2012-05-01 14:46 1706zccst整理 为方便直接使用,两个代码如下 (一)截图 ... -
javascript的一些效果的实现原理(一)
2012-02-25 11:53 1680作者:zccst 一、腾讯qq,鼠标移到头像上,展示个人信息 ... -
jquery 鼠标滚轮效果
2011-09-22 15:35 1399【译】鼠标滚轮来控制input框的值 http://www.r ...
相关推荐
jqweui图片上传插件jquery-weui.uploader.js 实现 多图上传,预览,删除,初始化控件,图片赋值加载,获取图片数据。压缩包包含jquery-weui.uploader.js,weui以及示例demo
文档里有附件,封装的webuploader,对象形式传参,一句话调用,自定义上传流程回调函数,带进度条,本地删除,远程删除,MD5校验等
一个Vue.js上传组件,由simple-uploader.js提供支持.zip
WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。...两套运行时,同样的调用方式,可供用户任意选用。 采用大文件分片并发上传,...uploader.swf用于webuploader的初始化
Cute WebUI AjaxUploader注册文件(AjaxUploader.lic) AjaxUploader.lic 注册版文件,测试可用。
由驱动的Vue.js上传组件 特征 将文件夹和文件视为File 暂停/继续上传 恢复上传 错误处理 使用文件夹阅读器拖放 自定义上传按钮 资料夹上载 队列管理 文件验证 上传进度 剩余时间 块上传 安装 npm install vue-...
该文件包内包含jquery.fineuploader3.7.1.js和fineuploader.css 该包用于用户学习、使用关于文件上传相关的内容时下载。
NULL 博文链接:https://chenwes.iteye.com/blog/1525161
最新版fineuploader.js
系统不支持FLASH的swf上传后,用Html5上传所有的JS适用于多图上传,
NULL 博文链接:https://jm1999.iteye.com/blog/2243337
WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的FLASH运行时,兼容IE6+,iOS 6+,...
stats_uploader.exe
前端项目-simple-uploader,A HTML5 upload component without UI
Appuploader是一个IOS开发助手,可以快速,轻松地生成ios开发证书,不需要钥匙串助手; appuploader可以批量上传屏幕截图并将ipa文件上传到Apple商店,在windows,linux或mac上,不需要应用程序加载器和mac计算机。 ...
使用MicroPython File Uploader或者uPyCraf进行开发 个人使用觉得MicroPython File Uploader适合指令开发,而uPyCraft更适合文件类型的开发。 绝对有用!
ImageUploader.rar 图片批量上传
A2Uploader.zip
Uploader是非常强大的异步文件上传组件,支持ajax、iframe、flash三套方案,实现浏览器的全兼容,调用非常简单,内置多套主题支持 和常用插件,比如验证、图片预览、进度条等,广泛应用于淘宝网,比如退款系统、...