ajaxupload.js php,AjaxUpLoad.js实现文件上传

/**

* AJAX Upload ( http://valums.com/ajax-upload/ )

* Copyright (c) Andris Valums

* Licensed under the MIT license ( http://valums.com/mit-license/ )

* Thanks to Gary Haran, David Mark, Corey Burns and others for contributions

*/

(function () {

/* global window */

/* jslint browser: true, devel: true, undef: true, nomen: true, bitwise: true, regexp: true, newcap: true, immed: true */

/**

* Wrapper for FireBug's console.log

*/

function log() {

if (typeof(console) != 'undefined' && typeof(console.log) == 'function') {

Array.prototype.unshift.call(arguments, '[Ajax Upload]');

console.log(Array.prototype.join.call(arguments, ' '));

}

}

/**

* Attaches event to a dom element.

* @param {Element} el

* @param type event name

* @param fn callback This refers to the passed element

*/

function addEvent(el, type, fn) {

if (el.addEventListener) {

el.addEventListener(type, fn, false);

} else if (el.attachEvent) {

el.attachEvent('on' + type, function () {

fn.call(el);

});

} else {

throw new Error('not supported or DOM not loaded');

}

}

/**

* Attaches resize event to a window, limiting

* number of event fired. Fires only when encounteres

* delay of 100 after series of events.

*

* Some browsers fire event multiple times when resizing

* http://www.quirksmode.org/dom/events/resize.html

*

* @param fn callback This refers to the passed element

*/

function addResizeEvent(fn) {

var timeout;

addEvent(window, 'resize', function () {

if (timeout) {

clearTimeout(timeout);

}

timeout = setTimeout(fn, 100);

});

}

// Needs more testing, will be rewriten for next version

// getOffset function copied from jQuery lib (http://jquery.com/)

if (document.documentElement.getBoundingClientRect) {

// Get Offset using getBoundingClientRect

// http://ejohn.org/blog/getboundingclientrect-is-awesome/

var getOffset = function (el) {

var box = el.getBoundingClientRect();

var doc = el.ownerDocument;

var body = doc.body;

var docElem = doc.documentElement; // for ie

var clientTop = docElem.clientTop || body.clientTop || 0;

var clientLeft = docElem.clientLeft || body.clientLeft || 0;

// In Internet Explorer 7 getBoundingClientRect property is treated as physical,

// while others are logical. Make all logical, like in IE8.

var zoom = 1;

if (body.getBoundingClientRect) {

var bound = body.getBoundingClientRect();

zoom = (bound.right - bound.left) / body.clientWidth;

}

if (zoom > 1) {

clientTop = 0;

clientLeft = 0;

}

var top = box.top / zoom + (window.pageYOffset || docElem && docElem.scrollTop / zoom || body.scrollTop / zoom) - clientTop,

left = box.left / zoom + (window.pageXOffset || docElem && docElem.scrollLeft / zoom || body.scrollLeft / zoom) - clientLeft;

return {

top: top,

left: left

};

};

} else {

// Get offset adding all offsets

var getOffset = function (el) {

var top = 0,

left = 0;

do {

top += el.offsetTop || 0;

left += el.offsetLeft || 0;

el = el.offsetParent;

} while (el);

return {

left: left,

top: top

};

};

}

/**

* Returns left, top, right and bottom properties describing the border-box,

* in pixels, with the top-left relative to the body

* @param {Element} el

* @return {Object} Contains left, top, right,bottom

*/

function getBox(el) {

var left, right, top, bottom;

var offset = getOffset(el);

left = offset.left;

top = offset.top;

right = left + el.offsetWidth;

bottom = top + el.offsetHeight;

return {

left: left,

right: right,

top: top,

bottom: bottom

};

}

/**

* Helper that takes object literal

* and add all properties to element.style

* @param {Element} el

* @param {Object} styles

*/

function addStyles(el, styles) {

for (var name in styles) {

if (styles.hasOwnProperty(name)) {

el.style[name] = styles[name];

}

}

}

/**

* Function places an absolutely positioned

* element on top of the specified element

* copying position and dimentions.

* @param {Element} from

* @param {Element} to

*/

function copyLayout(from, to) {

var box = getBox(from);

addStyles(to, {

position: 'absolute',

left: box.left + 'px',

top: box.top + 'px',

width: from.offsetWidth + 'px',

height: from.offsetHeight + 'px'

});

}

/**

* Creates and returns element from html chunk

* Uses innerHTML to create an element

*/

var toElement = (function () {

var div = document.createElement('div');

return function (html) {

div.innerHTML = html;

var el = div.firstChild;

return div.removeChild(el);

};

})();

/**

* Function generates unique id

* @return unique id

*/

var getUID = (function () {

var id = 0;

return function () {

return 'ValumsAjaxUpload' + id++;

};

})();

/**

* Get file name from path

* @param {String} file path to file

* @return filename

*/

function fileFromPath(file) {

return file.replace(/.*(\/|\\)/, "");

}

/**

* Get file extension lowercase

* @param {String} file name

* @return file extenstion

*/

function getExt(file) {

return (-1 !== file.indexOf('.')) ? file.replace(/.*[.]/, '') : '';

}

function hasClass(el, name) {

var re = new RegExp('\\b' + name + '\\b');

return re.test(el.className);

}

function addClass(el, name) {

if (!hasClass(el, name)) {

el.className += ' ' + name;

}

}

function removeClass(el, name) {

var re = new RegExp('\\b' + name + '\\b');

el.className = el.className.replace(re, '');

}

function removeNode(el) {

el.parentNode.removeChild(el);

}

/**

* Easy styling and uploading

* @constructor

* @param button An element you want convert to

* upload button. Tested dimentions up to 500x500px

* @param {Object} options See defaults below.

*/

window.AjaxUpload = function (button, options) {

this._settings = {

// Location of the server-side upload script

action: 'upload.php',

// File upload name

name: 'userfile',

// Additional data to send

data: {},

// Submit file as soon as it's selected

autoSubmit: true,

// The type of data that you're expecting back from the server.

// html and xml are detected automatically.

// Only useful when you are using json data as a response.

// Set to "json" in that case.

responseType: false,

// Class applied to button when mouse is hovered

hoverClass: 'hover',

// Class applied to button when AU is disabled

disabledClass: 'disabled',

// When user selects a file, useful with autoSubmit disabled

// You can return false to cancel upload

onChange: function (file, extension) {},

// Callback to fire before file is uploaded

// You can return false to cancel upload

onSubmit: function (file, extension) {},

// Fired when file upload is completed

// WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE!

onComplete: function (file, response) {}

};

// Merge the users options with our defaults

for (var i in options) {

if (options.hasOwnProperty(i)) {

this._settings[i] = options[i];

}

}

// button isn't necessary a dom element

if (button.jquery) {

// jQuery object was passed

button = button[0];

} else if (typeof button == "string") {

if (/^#.*/.test(button)) {

// If jQuery user passes #elementId don't break it

button = button.slice(1);

}

button = document.getElementById(button);

}

if (!button || button.nodeType !== 1) {

throw new Error("Please make sure that you're passing a valid element");

}

if (button.nodeName.toUpperCase() == 'A') {

// disable link

addEvent(button, 'click', function (e) {

if (e && e.preventDefault) {

e.preventDefault();

} else if (window.event) {

window.event.returnValue = false;

}

});

}

// DOM element

this._button = button;

// DOM element

this._input = null;

// If disabled clicking on button won't do anything

this._disabled = false;

// if the button was disabled before refresh if will remain

// disabled in FireFox, let's fix it

this.enable();

this._rerouteClicks();

};

// assigning methods to our class

AjaxUpload.prototype = {

setData: function (data) {

this._settings.data = data;

},

disable: function () {

addClass(this._button, this._settings.disabledClass);

this._disabled = true;

var nodeName = this._button.nodeName.toUpperCase();

if (nodeName == 'INPUT' || nodeName == 'BUTTON') {

this._button.setAttribute('disabled', 'disabled');

}

// hide input

if (this._input) {

// We use visibility instead of display to fix problem with Safari 4

// The problem is that the value of input doesn't change if it

// has display none when user selects a file

this._input.parentNode.style.visibility = 'hidden';

}

},

enable: function () {

removeClass(this._button, this._settings.disabledClass);

this._button.removeAttribute('disabled');

this._disabled = false;

},

/**

* Creates invisible file input

* that will hover above the button

*

*/

_createInput: function () {

var self = this;

var input = document.createElement("input");

input.setAttribute('type', 'file');

input.setAttribute('name', this._settings.name);

addStyles(input, {

'position': 'absolute',

// in Opera only 'browse' button

// is clickable and it is located at

// the right side of the input

'right': 0,

'margin': 0,

'padding': 0,

'fontSize': '480px',

'cursor': 'pointer'

});

var div = document.createElement("div");

addStyles(div, {

'display': 'block',

'position': 'absolute',

'overflow': 'hidden',

'margin': 0,

'padding': 0,

'opacity': 0,

// Make sure browse button is in the right side

// in Internet Explorer

'direction': 'ltr',

//Max zIndex supported by Opera 9.0-9.2

'zIndex': 2147483583

});

// Make sure that element opacity exists.

// Otherwise use IE filter

if (div.style.opacity !== "0") {

if (typeof(div.filters) == 'undefined') {

throw new Error('Opacity not supported by the browser');

}

div.style.filter = "alpha(opacity=0)";

}

addEvent(input, 'change', function () {

if (!input || input.value === '') {

return;

}

// Get filename from input, required

// as some browsers have path instead of it

var file = fileFromPath(input.value);

if (false === self._settings.onChange.call(self, file, getExt(file))) {

self._clearInput();

return;

}

// Submit form when value is changed

if (self._settings.autoSubmit) {

self.submit();

}

});

addEvent(input, 'mouseover', function () {

addClass(self._button, self._settings.hoverClass);

});

addEvent(input, 'mouseout', function () {

removeClass(self._button, self._settings.hoverClass);

// We use visibility instead of display to fix problem with Safari 4

// The problem is that the value of input doesn't change if it

// has display none when user selects a file

input.parentNode.style.visibility = 'hidden';

});

div.appendChild(input);

document.body.appendChild(div);

this._input = input;

},

_clearInput: function () {

if (!this._input) {

return;

}

// this._input.value = ''; Doesn't work in IE6

removeNode(this._input.parentNode);

this._input = null;

this._createInput();

removeClass(this._button, this._settings.hoverClass);

},

/**

* Function makes sure that when user clicks upload button,

* the this._input is clicked instead

*/

_rerouteClicks: function () {

var self = this;

// IE will later display 'access denied' error

// if you use using self._input.click()

// other browsers just ignore click()

addEvent(self._button, 'mouseover', function () {

if (self._disabled) {

return;

}

if (!self._input) {

self._createInput();

}

var div = self._input.parentNode;

copyLayout(self._button, div);

div.style.visibility = 'visible';

});

// commented because we now hide input on mouseleave

/**

* When the window is resized the elements

* can be misaligned if button position depends

* on window size

*/

//addResizeEvent(function(){

// if (self._input){

// copyLayout(self._button, self._input.parentNode);

// }

//});

},

/**

* Creates iframe with unique name

* @return {Element} iframe

*/

_createIframe: function () {

// We can't use getTime, because it sometimes return

// same value in safari :(

var id = getUID();

// We can't use following code as the name attribute

// won't be properly registered in IE6, and new window

// on form submit will open

// var iframe = document.createElement('iframe');

// iframe.setAttribute('name', id);

var iframe = toElement('');

// src="javascript:false; was added

// because it possibly removes ie6 prompt

// "This page contains both secure and nonsecure items"

// Anyway, it doesn't do any harm.

iframe.setAttribute('id', id);

iframe.style.display = 'none';

document.body.appendChild(iframe);

return iframe;

},

/**

* Creates form, that will be submitted to iframe

* @param {Element} iframe Where to submit

* @return {Element} form

*/

_createForm: function (iframe) {

var settings = this._settings;

// We can't use the following code in IE6

// var form = document.createElement('form');

// form.setAttribute('method', 'post');

// form.setAttribute('enctype', 'multipart/form-data');

// Because in this case file won't be attached to request

var form = toElement('

');

form.setAttribute('action', settings.action);

form.setAttribute('target', iframe.name);

form.style.display = 'none';

document.body.appendChild(form);

// Create hidden input element for each data key

for (var prop in settings.data) {

if (settings.data.hasOwnProperty(prop)) {

var el = document.createElement("input");

el.setAttribute('type', 'hidden');

el.setAttribute('name', prop);

el.setAttribute('value', settings.data[prop]);

form.appendChild(el);

}

}

return form;

},

/**

* Gets response from iframe and fires onComplete event when ready

* @param iframe

* @param file Filename to use in onComplete callback

*/

_getResponse: function (iframe, file) {

// getting response

var toDeleteFlag = false,

self = this,

settings = this._settings;

addEvent(iframe, 'load', function () {

if ( // For Safari

iframe.src == "javascript:'%3Chtml%3E%3C/html%3E';" ||

// For FF, IE

iframe.src == "javascript:'';") {

// First time around, do not delete.

// We reload to blank page, so that reloading main page

// does not re-submit the post.

if (toDeleteFlag) {

// Fix busy state in FF3

setTimeout(function () {

removeNode(iframe);

},

0);

}

return;

}

var doc = iframe.contentDocument ? iframe.contentDocument : window.frames[iframe.id].document;

// fixing Opera 9.26,10.00

if (doc.readyState && doc.readyState != 'complete') {

// Opera fires load event multiple times

// Even when the DOM is not ready yet

// this fix should not affect other browsers

return;

}

// fixing Opera 9.64

if (doc.body && doc.body.innerHTML == "false") {

// In Opera 9.64 event was fired second time

// when body.innerHTML changed from false

// to server response approx. after 1 sec

return;

}

var response;

if (doc.XMLDocument) {

// response is a xml document Internet Explorer property

response = doc.XMLDocument;

} else if (doc.body) {

// response is html document or plain text

response = doc.body.innerHTML;

if (settings.responseType && settings.responseType.toLowerCase() == 'json') {

// If the document was sent as 'application/javascript' or

// 'text/javascript', then the browser wraps the text in a

 
 

// tag and performs html encoding on the contents. In this case,

// we need to pull the original text content from the text node's

// nodeValue property to retrieve the unmangled content.

// Note that IE6 only understands text/html

if (doc.body.firstChild && doc.body.firstChild.nodeName.toUpperCase() == 'PRE') {

response = doc.body.firstChild.firstChild.nodeValue;

}

if (response) {

response = eval("(" + response + ")");

} else {

response = {};

}

}

} else {

// response is a xml document

response = doc;

}

settings.onComplete.call(self, file, response);

// Reload blank page, so that reloading main page

// does not re-submit the post. Also, remember to

// delete the frame

toDeleteFlag = true;

// Fix IE mixed content issue

iframe.src = "javascript:'';";

});

},

/**

* Upload file contained in this._input

*/

submit: function () {

var self = this,

settings = this._settings;

if (!this._input || this._input.value === '') {

return;

}

var file = fileFromPath(this._input.value);

// user returned false to cancel upload

if (false === settings.onSubmit.call(this, file, getExt(file))) {

this._clearInput();

return;

}

// sending request

var iframe = this._createIframe();

var form = this._createForm(iframe);

// assuming following structure

// div -> input type='file'

removeNode(this._input.parentNode);

removeClass(self._button, self._settings.hoverClass);

form.appendChild(this._input);

form.submit();

// request set, clean up

removeNode(form);

form = null;

removeNode(this._input);

this._input = null;

// Get response from iframe and fire onComplete event when ready

this._getResponse(iframe, file);

// get ready for next request

this._createInput();

}

};

})();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值