|
|
/*!
|
|
|
* 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); |