outerHeight()包括内边距和边框,输入includeMargin参数就可以包括外边距
innerHeight()包括内边距、不包括边框
height()随浏览器的盒模式作相应的改变
css(‘height’)包含px单位
?
offset()获取元素相对文档的偏移量,.left和.top取左右偏移及上下偏移
?
2.jQuery补遗
jQuery工具函数
$.extend(target,[object1],[objectN])
将object1……objectN合并到target对象中,键值相同的项将被替换
用途:替换默认的配置项$.extend(default,options)
代码实现:
?
$.extend([deep],target,object1,[objectN])
深拷贝的方式,子项也将被递归合并
?
$.extend(object)
扩展jQuery类,即为静态方法
?
$.fn.extend(object)
扩展jQuery对象的方法,即为原型属性上的公有方法
?
$.each(object, [callback])
遍历数组或者对象
?
$.grep(array, callback, [invert])
根据回调函数过滤数组,invert默认为false,回调函数返回值为true的项构成结果集
?
$.makeArray(obj)
将类数组对象arguments转化成数组,可以应用数组的方法
?
$.map(arr|obj,callback)
对数组元素进行操作后构成新数组,利用null以及[]的形式裁断或增加数组元素的数目
?
$.inArray(value,array,[fromIndex])
返回value在数组中的索引,不在数组中返回-1,fromIndex起始位置
?
$.merge(first,second)
第二个数组的元素跟在第一个数组的元素后面输出,并替换第一个数组
?
$.unique(array)
处理DOM元素,删除重复的数组
?
$.parseJSON(json)
将json形式的字符串(双引号包裹)转化成json对象输出,可以用键值对读取
?
jQuery-ajax
暂缺
?
3.HTML5新技术
FileList对象(ie8无法用输入框获取文件对象)
<input type=’file’>元素的files属性中包含文件对象,设置multiple属性可以支持多文件上传,该File对象继承Blob,包含size、type(MIME类型)属性、slice方法,在此基础上又扩展出name、lastModifiedDate两个属性
获取该对象可使用
document.getElementById(‘idname’).files[0]
?
FileReader对象
首先创建一个FileReader实例,其次有三个方法可供调用,均为异步读取,通过监听对象的onload事件读取result数据,abort方法停止读取
readAsBinaryString(Blob blob)传入blob对象(file对象继承blob对象),然后将读取数据的结果作为二进制的形式放大片FileReader对象的result属性里;
readAsText(Blob blob, optional DOMString encoding)传入blob对象、编码格式,以文本字符串形式存储在result中;
readAsDataURL(Blob blob)传入blob对象,读取内容作为url属性,处理图片的src地址
调用方法
var resultFile = document.getElementById("fileDemo").files[0];
if (resultFile) {
var reader = new FileReader();
reader.readAsDataURL(resultFile);
reader.onload = function (e) {
console.log(this.result) ;
};
}
?
http://www.cnblogs.com/fly_dragon/archive/2012/06/02/2532035.html
?
FormData对象
首先创建一个FormData实例,然后使用append方法往该实例中加入键值对,可以是简单的数据,也可以是blob对象或者文件对象,再通过ajax的方式将该实例发送给后台;
另一种方式是使用表单元素创建实例,如new FormData(someformelement)
示例(问题是后台怎么接受):
var newFormData = new FormData(someFormElement);
newFormData.append("accountnum", 123456);
newFormData .append("userfile", fileInputElement.files[0]);
var oFileBody = "<a id="a"><b id="b">hey!</b></a>"; // Blob对象包含的文件内容
var oBlob = new Blob([oFileBody], { type: "text/xml"});
newFormData.append("webmasterfile", oBlob);
?
http://www.cnblogs.com/lhb25/p/html5-formdata-tutorials.html
?
4.upload插件的使用
配置项(form表单上传文件的时候,需要添加enctype="multipart/form-data"):
trigger触发元素,即点击后能弹出对话框的元素,和form、<input type=’file’>同等大小
accept限定上传文件的类型,<input type=’file’>的accept属性
action上传地址,form的action属性,ajax的url,关联后台的方法或url
name文件的名字
data附带的数据,form通过input上传,ajax通过额外的上传数据
multiple是否允许多文件上传
change上传文件的输入框改变时调用,上下文是上传输入框,参数是文件对象
success、error上传成功或失败时调用,form通过iframe加载解析文档内容,ajax直接返回
progress上传进度的函数function(event, position, total, percent, files){}
?
调用方式是new出一个Uploader实例或者new出一个MultipleUploader实例(针对多个上传文件input的情况,以数组形式传入相应的trigger)
示例:
var uploader = new Uploader({
trigger: ‘.upload-btn‘,
name: ‘image‘,
action: ‘/upload‘,
accept: ‘image/*‘,
data: {‘xsrf‘: ‘hash‘},
multiple: true,
error: function(file) {
alert(122);
},
success: function(response) {
alert(response);
},
progress: function(event, position, total, percent, files) {
console.log(percent);
}
});
?
5.upload插件的源码
架构:
对支持html5的浏览器使用ajax的方式上传,不支持的浏览器使用表单上传,通过iframe禁止页面刷新,以及获取后台返回的响应
源码:
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);// 触发元素,创建的form和<input type=‘file‘>和它同等大小,点击弹出文件选择对话框
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();
}
Uploader.prototype.setup = function() {
this.form = $(
‘<form method="post" enctype="multipart/form-data"‘
+ ‘target="" action="‘ + this.settings.action + ‘" />‘
);
//调用newIframe函数创建新的iframe框架,createInputs创建输入框,键值对作为name和value
this.iframe = newIframe();
this.form.attr(‘target‘, this.iframe.attr(‘name‘));
var data = this.settings.data;
this.form.append(createInputs(data));
if (window.FormData) {
this.form.append(createInputs({‘_uploader_‘: ‘formdata‘}));
} else {
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);
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)
});
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‘);
return this;
};
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
self._files = this.files || [{
name: e.target.value
}];
var file = self.input.val();
if (self.settings.change) {
self.settings.change.call(self, self._files);
} else if (file) {
return self.submit();
}
});
};
Uploader.prototype.submit = function() {
var self = this;
if (window.FormData && self._files) {
var form = new FormData(self.form.get(0));// 表单元素即包含上传输入框,为什么还要往formdata对象中添加文件???
form.append(self.settings.name, self._files);
var optionXhr;
if (self.settings.progress) {
var files = self._files;
optionXhr = function() {
var xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener(‘progress‘, function(event) {
var percent = 0;
console.log(event.loaded)
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,
success: self.settings.success,
error: self.settings.error
});
return this;
} else {
self.iframe = newIframe();// 之前创建一个iframe,何必再创建???
self.form.attr(‘target‘, self.iframe.attr(‘name‘));
$(‘body‘).append(self.iframe);
self.iframe.one(‘load‘, function() {
// 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;
try {
response = $(this).contents().find("body").html();// contents()获取直接子节点,包含文本节点和html节点
} catch (e) {
response = "cross-domain";
}
$(this).remove();
if (!response) {
if (self.settings.error) {// ajax上传成功失败时调用接口,表单上传需要传入相应的参数
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();
};
Uploader.prototype.change = function(callback) {
if (!callback) {
return this;
}
this.settings.change = callback;
return this;
};
Uploader.prototype.success = function(callback) {
var me = this;
this.settings.success = function(response) {
me.refreshInput();
if (callback) {
callback(response);
}
};
return this;
};
Uploader.prototype.error = function(callback) {
var me = this;
this.settings.error = function(response) {
if (callback) {
me.refreshInput();
callback(response);
}
};
return this;
};
Uploader.prototype.enable = function(){
this.input.prop(‘disabled‘, false);
this.input.css(‘cursor‘, ‘pointer‘);
};
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) {// 解析a=3&b=4形式的字符串
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‘);// parentsUntil方法遍历寻找祖先元素,源自jquery
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 name="‘ + iframeName + ‘" />‘).hide();
iframeCount += 1;
return iframe;
}
//多个input元素时候的调用方式
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;
};
?
原文:http://schifred.iteye.com/blog/2268716