- 浏览: 3315924 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (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 1526作者:zccst 由单日历改为双日历,整整花了1.5天的实现 ... -
自己写插件的开始
2014-07-25 18:06 640作者:zccst 很久以前就会使用别人写好的插件了,大概是2 ... -
图片轮播(自己实现)
2014-05-27 22:27 1707作者:zccst 2014-09-21 图片轮播的思路是: ... -
插件实现原理-自己总结
2012-10-31 19:05 1246作者:zccst /*file1 ** gms.j ... -
图片轮播(多种实现)
2012-05-13 12:57 1317作者:zccst 图片轮播有很多种形式,且大多可复用性很高。 ... -
二级菜单(插件网址收藏)
2012-05-01 16:53 1014作者:zccst 较好的连接地址收藏: 1,阿里西西 批注 ... -
二级菜单(两个源代码)
2012-05-01 14:46 1730zccst整理 为方便直接使用,两个代码如下 (一)截图 ... -
javascript的一些效果的实现原理(一)
2012-02-25 11:53 1709作者:zccst 一、腾讯qq,鼠标移到头像上,展示个人信息 ... -
jquery 鼠标滚轮效果
2011-09-22 15:35 1450【译】鼠标滚轮来控制input框的值 http://www.r ...
相关推荐
`fileuploader.js`是一个轻量级的前端文件上传组件,它提供了友好的API和自定义选项,便于开发者集成到自己的项目中。该库的核心特性包括多文件选择、进度显示、错误处理和自定义样式等。通过阅读博文...
在这个"fineuploader3.7.1.js及css.rar"压缩包中,包含的主要组件是`jquery.fineuploader3.7.1.js`和`fineuploader.css`。这两个文件分别负责FineUploader的JavaScript逻辑和样式设计,使得在网页上实现文件上传变得...
【标题】:基于weui图片上传封装插件 在现代Web开发中,用户交互和界面体验成为了关键要素,尤其在移动应用中。...通过深入理解这个插件的工作原理和API,开发者可以更好地将其融入到实际项目中,提升用户交互体验。
WebUploader是由阿里云开发的一个JavaScript文件上传组件,它具有异步上传、断点续传、多文件上传、预览、裁剪等功能。`diyUpload.js`则是对WebUploader进行了一次定制化改造,使得其更适应移动端的使用场景,简化了...
`Swiff.Uploader.fla` 和 `Swiff.Uploader.js` 是该组件的核心部分,其中 `.fla` 文件是Flash的源文件,用于编辑和编译Flash代码,`.js` 文件则是与JavaScript交互的接口,用于在网页中实例化和控制Flash对象。...
4. **初始化SWFUpload**:在JavaScript中调用`SWFUpload.init()`方法启动组件。 5. **事件监听**:绑定各种事件监听器,如`fileQueued`、`uploadProgress`和`uploadSuccess`,以处理上传过程中的各种情况。 6. **...
在这个"百度的WebUploader组件实现普通文件的批量上传示例相关的js和css"的压缩包中,主要包含的是用于实现这一功能的JavaScript库文件和CSS样式文件。 首先,我们要理解WebUploader的工作原理。它基于HTML5的File ...
【webuploader】是一个轻量级的前端上传组件,主要用于网页上的文件上传操作。它支持多浏览器,包括IE6+,并且提供了丰富的API和多种自定义配置选项,方便开发者实现各种复杂的上传需求。在这个"webuploader-demo...
1. **Ajax原理**:Ajax的核心是 XMLHttpRequest 对象,它允许JavaScript在后台与服务器交换数据并更新部分网页内容,无需重新加载整个页面。通过创建XMLHttpRequest对象,打开连接,发送请求,监听状态变化,最终...
Web Uploader是一款强大的JavaScript文件上传组件,尤其在处理大文件上传和批量上传方面表现出色。在Web开发中,用户交互的文件上传功能是常见的需求,Web Uploader则为开发者提供了便利。这个“Web_Uploader_demo....
2. **JavaScript设置**:引入AjaxFileUpload.js库,然后创建一个新的AjaxFileUpload实例。配置参数如上传URL、回调函数等。 ```javascript var uploader = new AjaxFileUpload(); uploader.settings.url = 'upload....
WebUpload是一款轻量级、高效的文件上传组件,尤其适合在处理大量文件上传时提供良好的用户体验。 首先,我们需要理解WebUpload的基本概念。WebUpload是百度推出的一款JavaScript插件,它旨在简化文件上传流程,...
总之,JSP中使用JS上传组件涉及前端与后端的紧密协作,理解组件的工作原理和API,以及良好的前后端通信实践,是实现高效文件上传功能的关键。通过选择合适的组件,并结合JSP和JavaScript的特性,我们可以为用户提供...
WebUploader是一款强大的JavaScript文件上传组件,它专注于解决大文件上传的问题,尤其在处理多文件、断点续传以及预览功能上表现出色。这个组件由阿里云开发,旨在为Web应用提供灵活、高效的文件上传解决方案。 一...
2. `FileUploader.js`: JavaScript文件,实现了Ajax和HTML5上传的逻辑,以及与Flash组件的交互。 3. `UploadHandler.cs`: C#服务器端处理程序,负责接收并处理上传的文件。 4. `Demo.html`: 示例页面,展示了如何在...
4. "Swiff.Uploader.js" - 这可能是一个用于与Flash交互的JavaScript模块,因为Flash在上传大文件时曾经是常见的选择。 5. "fan.js", "Fx.ProgressBar.js" - 可能是Fancyupload的一部分,分别涉及用户界面的特定功能...
Element UI 是一套为开发者、设计师和产品经理准备的基于 Vue.js 的开源组件库,而Ruoyi则是一个轻量级的后台管理系统框架。这个组件的实现主要涉及到以下几个关键知识点: 1. **Element UI组件库**: Element UI ...
百度Web Uploader是一款强大的JavaScript文件上传组件,它支持多浏览器、拖拽上传、图片预览、进度显示等功能,并且提供了分片上传的能力,以应对大文件上传的需求。分片上传的主要原理是将大文件分割成多个小块(片...
在本文中,我们将深入探讨这个组件的核心功能、使用场景、工作原理以及如何在实际项目中集成和配置。 1. **核心功能**: - 多文件上传:UPU支持用户同时上传多个文件,提高了用户交互体验。 - 文件类型限制:可以...
Ajax-Uploader是一款强大的JavaScript库,专门用于在网页上实现异步文件上传功能。...同时,理解Ajax-Uploader的工作原理,有助于解决在实际开发中遇到的问题,提升文件上传模块的开发效率和质量。