You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

490 lines
14 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*!
* Squid 总结、积累、收集的一些基础方法
* http://www.cnblogs.com/typeof/
*
* 所有plugins、swing所做的扩展都是基于Squid对象
*/
(function(window) {
//定义squid
var Squid = function() {},
slice = Array.prototype.slice,
splice = Array.prototype.splice,
trim = String.prototype.trim;
//浅度拷贝
Squid.extend = function() {
var target = arguments[0],
i = 1,
length = arguments.length,
options,
prop;
if(typeof target !== 'object') {
target = {};
}
if(length === i) {
target = this;
--i;
}
for(; i < length; i++) {
if((options = arguments[i]) != null) {
for(prop in options) {
target[prop] = options[prop];
}
}
}
return target;
};
//DOM 方法
Squid.extend({
getElementById: function(id) {
var elem = document.getElementById(id);
if(elem && elem.parentNode) {
if(elem.id !== id) {
elem = null;
var elems = document.getElementsByTagName(id),
i = 0,
length = elems.length,
cur;
for(; i < length; i++) {
cur = elems[i];
if(cur.id === id) {
elem = cur;
break;
}
}
}
return elem;
}
},
getElementsByTagName: function(tagName, context) {
context = context || document;
var elems = context.getElementsByTagName(tagName),
r = [];
try {
r = slice.call(elems, 0);
}catch(e) {
var i = 0,
length = elems.length,
elem;
for(; i < length; i++) {
elem = elems[i];
r.push(elem);
}
}
return r;
},
getElementsByClassName: function(className, context) {
//执行上下文默认为document
context = context || document;
var r = [];
if(context.getElementsByClassName) {
var elems = context.getElementsByClassName(className);
r = slice.call(elems, 0);
}else{
var elems,
elem,
i = 0,
length;
elems = context.getElementsByTagName('*');
length = elems.length;
for(; i < length; i++) {
elem = elems[i];
if(elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(className) >= 0) {
r.push(elem);
}
}
}
return r;
},
children: function(elem) {
},
first: function(elem) {
return this.sibling(elem.firstChild)[0];
},
next: function(elem) {
return this.nth(elem, 2, 'nextSibling');
},
siblings: function(elem) {
return this.sibling(elem.parentNode.firstChild, elem);
},
nth: function(cur, r, dir) {
r = r || 1;
var i = 0;
for(; cur; cur = cur[dir]) {
if(cur.nodeType === 1 && ++i === r) {
break;
}
}
return cur;
},
sibling: function(n, elem) {
var r = [];
for(; n; n = n.nextSibling) {
if(n.nodeType === 1 && n !== elem) {
r.push(n);
}
}
return r;
},
isVisible: function(elem) {
return !this.isHidden(elem);
},
isHidden: function(elem) {
if(elem) {
var width = elem.offsetWidth,
height = elem.offsetHeight;
return (width === 0 && height === 0) || elem.style.display === 'none'
}
},
getOffset: function(elem) {
var body = document.body,
docElem = document.documentElement;
if('getBoundingClientRect' in document.documentElement) {
var box;
try {
box = elem.getBoundingClientRect()
}catch(e) {}
if(!box || !elem.parentNode) {
return box ? {top: box.top, left: box.left} : {top: 0, left: 0}
}
var win = window,
clientTop = docElem.clientTop || body.clientTop || 0,
clientLeft = docElem.clientLeft || body.clientLeft || 0,
scrollTop = win.pageYOffset || docElem.scrollTop || body.scrollTop,
scrollLeft = win.pageXOffset || docElem.scrollLeft || body.scrollLeft,
top = box.top + scrollTop - clientTop,
left = box.left + scrollLeft - clientLeft;
return {top: top, left: left}
}else{
var offsetParent = elem.offsetParent,
top = elem.offsetTop,
left = elem.offsetLeft;
while((elem = elem.parentNode) && elem !== body && elem !== docElem) {
if(elem === offsetParent) {
top = elem.offsetTop
left = elem.offsetLeft
offsetParent = elem.offsetParent
}
}
return {top: top, left: left}
}
},
position: function(elem) {
if(!elem) {
return null;
}
var offsetParent = elem.offsetParent,
offset = this.getOffset(elem),
parentOffset = this.getOffset(offsetParent);
return {
top: offset.top - parentOffset.top,
left: offset.left - parentOffset.left
};
}
});
//全局缓存对象
var cache = {};
Squid.extend({
guid: 1,
uuid: 0,
expando: 'squid' + (Math.random() + '').replace(/\D/g, ''),
data: function(elem, name) {
var internalKey = squid.expando,
id,
thisCache,
r;
id = elem[squid.expando];
if(!id) {
elem[squid.expando] = id = ++squid.uuid;
}
if(!cache[id]) {
cache[id] = {};
}
if(typeof name === 'object' || typeof name === 'function') {
cache[id][internalKey] = name;
}
thisCache = cache[id];
if(!thisCache[internalKey]) {
thisCache[internalKey] = {};
}
thisCache = thisCache[internalKey];
if(name === 'events' && !thisCache[name]) {
return thisCache[internalKey] && thisCache[internalKey].events;
}
if(typeof name === 'string') {
r = thisCache[name];
}else{
r = thisCache;
}
return r;
},
removeData: function(elem, name) {
var internalKey = squid.expando,
id = elem[squid.expando],
internalCache;
if(!cache[id]) {
return;
}
try{
delete cache[id];
}catch(e) {
cache[id] = null;
}
if(elem.removeAttribute) {
elem.removeAttribute(squid.expando);
}else{
elem[squid.expando] = null;
}
}
});
//事件处理
Squid.event = {
add: function(elem, type, handler) {
var elemData,
events,
eventHandler,
handleObj,
handlers;
if(elem.nodeType === 3 || elem.nodeType === 8) {
return;
}
if(!handler) {
return;
}
if(!handler.guid) {
handler.guid = squid.guid++;
}
elemData = squid.data(elem);
if(!elemData) {
return;
}
events = elemData.events;
eventHandler = elemData.handle;
if(!events) {
elemData.events = events = {};
}
if(!eventHandler) {
elemData.handle = eventHandler = function(event) {
return squid.event.handle.apply(eventHandler.elem, arguments);
};
eventHandler.elem = elem;
}
handleObj = {
handler: handler
};
handleObj.type = type;
if(!handleObj.guid) {
handleObj.guid = handler.guid;
}
handlers = events[type];
if(!handlers) {
handlers = events[type] = [];
if(elem.addEventListener) {
elem.addEventListener(type, eventHandler, false);
}else if(elem.attachEvent){
elem.attachEvent('on' + type, eventHandler);
}
}
handlers.push(handleObj);
},
remove: function(elem, type, handler) {
var elemData,
events,
eventType,
i = 0,
handleObj;
if(elem.nodeType === 3 || elem.nodeType === 8) {
return;
}
elemData = squid.data(elem);
events = elemData.events;
if(!events) {
return;
}
eventType = events[type] || [];
if(!handler) {
for(; i < eventType.length; i++) {
handleObj = eventType[i];
squid.event.remove(elem, type, handleObj.handler);
eventType.splice(i--, 1);
}
}
if(eventType.length === 0) {
if(elem.removeEventListener) {
elem.removeEventListener(type, elemData.handle, false);
}else if(elem.detachEvent) {
elem.detachEvent('on' + type, elemData.handle);
}
}
squid.removeData(elem);
},
handle: function(event) {
var i = 0,
length,
handlers,
handleObj,
args = Array.prototype.slice.call(arguments, 0);
event = squid.event.fix(event);
handlers = ((squid.data(this, 'events') || {})[event.type] || []).slice(0);
args[0] = event;
length = handlers.length;
for(; i < length; i++) {
handleObj = handlers[i];
event.handler = handleObj.handler;
event.handleObj = handleObj;
handleObj.handler.apply(this, args);
}
},
fix: function(event) {
if(!event.target) {
event.target = event.srcElement || document;
}
if(event.target.nodeType === 3) {
event.target = event.target.parentNode;
}
if(!event.relateTarget && event.fromElement) {
event.relateTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
}
if(!event.preventDefault) {
event.preventDefault = function() {
event.returnValue = false;
};
}
if(!event.stopPropagation) {
event.stopPropagation = function() {
event.cancelBubble = true;
};
}
if(event.pageX == null) {
var eventDoc = event.target.ownerDocument || document,
doc = eventDoc.documentElment,
body = eventDoc.body;
event.pageX = event.clientX + (doc && document.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = event.clientY + (doc && document.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
}
return event;
}
};
//事件处理
Squid.extend({
on: function(elem, type, handler) {
return this.event.add(elem, type, handler);
},
off: function(elem, type, handler) {
return this.event.remove(elem, type, handler);
},
//把函数放到特定上下文执行
proxy: function(fn, context) {
var slice = Array.prototype.slice,
args = slice.call(arguments, 2),
proxy = function() {
return fn.apply(context, args.concat(slice.call(arguments)));
};
proxy.guid = fn.guid = fn.guid || proxy.guid || squid.guid++;
return proxy;
}
});
var fnThrottleId = 0;
//工具函数
Squid.extend({
trim: trim ? function(text) {
return trim.call(text);
} : function(text) {
return text.toString().replace(/^\s+/, '').replace(/\s+$/, '');
},
throttle: function(fn, delay, context) {
delay = delay || 100;
context = context || null;
return function() {
var args = arguments;
clearTimeout(fnThrottleId);
fnThrottleId = setTimeout(function() {
fn.apply(context, args);
}, delay);
};
},
isEmpty: function(obj) {
for(var prop in obj) {
return false;
}
return true;
}
});
//基于Squid扩展的插件
Squid.plugin = function() {};
//解决浏览器对默认组件渲染不一样
Squid.swing = function() {};
window.squid = Squid;
})(window);