1 $util = {
2 /**
3 * 类型检测
4 */
5 type : function(obj){
6 var rep = /\[object\s+(\w+)\]/i;
7 var str = Object.prototype.toString.call(obj).toLowerCase();
8 str.match(rep);
9 return RegExp.$1;
10 },
11 /**
12 * 深拷贝
13 */
14 $unlink :function (object){
15 var unlinked;
16 switch ($type(object)){
17 case 'object':
18 unlinked = {};
19 for (var p in object) {
20 unlinked[p] = $unlink(object[p]);
21 }
22 break;
23 case 'array':
24 unlinked = [];
25 for (var i = 0, l = object.length; i < l; i++) {
26 unlinked[i] = $unlink(object[i]);
27 }
28 break;
29 default: return object;
30 }
31 return unlinked;
32 },
33 /**
34 *Dom 相关操作
35 */
36 dom:{
37 $: function(id) {
38 return document.getElementById(id);
39 },
40 getStyle: function(obj, prop) {
41 var style = obj.currentStyle || window.getComputedStyle(obj, '');
42 if (obj.style.filter) {
43 return obj.style.filter.match(/\d+/g)[0];
44 }
45 return style[prop];
46 },
47 setStyle: function(obj, prop, val) {
48 switch (prop) {
49 case 'opacity':
50 if($util.client.browser.ie){
51 obj.style.filter = 'alpha(' + prop + '=' + val*100 + ')'
52 }else{
53 obj.style[prop] = val;
54 }
55 break;
56 default:
57 obj.style[prop] = val + 'px';
58 break;
59 }
60 },
61 setStyles: function(obj, props) {
62 for (var prop in props) {
63 switch (prop) {
64 case 'opacity':
65 if($util.client.browser.ie){
66 obj.style.filter = 'alpha(' + prop + '=' + props[prop] + ')'
67 }else{
68 obj.style[prop] = props[prop];
69 }
70 break;
71 default:
72 obj.style[prop] = props[prop] + 'px';
73 break;
74 }
75 }
76 }
77 },
78 /**
79 *Event 事件相关
80 */
81 evt : {
82 addEvent : function(oTarget, sEventType, fnHandler) {
83 if (oTarget.addEventListener) {
84 oTarget.addEventListener(sEventType, fnHandler, false);
85 } else if (oTarget.attachEvent) {
86 oTarget.attachEvent("on" + sEventType, fnHandler);
87 } else {
88 oTarget["on" + sEventType] = fnHandler;
89 }
90 },
91 rmEvent : function removeEventHandler (oTarget, sEventType, fnHandler) {
92 if (oTarget.removeEventListener) {
93 oTarget.removeEventListener(sEventType, fnHandler, false);
94 } else if (oTarget.detachEvent) {
95 oTarget.detachEvent("on" + sEventType, fnHandler);
96 } else {
97 oTarget["on" + sEventType] = null;
98 }
99 }
100 },
101 /**
102 *Ajax 异步加载
103 */
104 ajax : {
105 request:function (options) {
106 var xhr, res;
107 var url = options.url,
108 context = options.context,
109 success = options.success,
110 type = options.type,
111 datatype = options.datatype,
112 async = options.async,
113 send = options.send,
114 headers = options.headers;
115
116 try {
117 xhr = new XMLHttpRequest();
118 } catch(e) {
119 try {
120 xhr = new ActiveXObject('MSXML2.XMLHTTP');
121 } catch(e) {
122 xhr = new ActiveXObject('Microsoft.XMLHTTP');
123 }
124 }
125
126 xhr.onreadystatechange = function() {
127 if (xhr.readyState == 4 && xhr.status == 200) {
128 res = xhr.responseText;
129 success(res);
130 }
131 }
132 xhr.open(type, url, async);
133 xhr.send(send);
134 }
135 },
136 /**
137 *Array 数组相关
138 */
139 array : {
140 minIndex : function(ary){
141 return Math.min.apply(null,ary);
142 },
143 maxitem : function(ary){
144 return Math.max.apply(null,ary);
145 }
146 },
147 /**
148 *Client 客户端检测
149 */
150 client : function(){
151 // 浏览器渲染引擎 engines
152 var engine = {
153 ie: 0,
154 gecko: 0,
155 webkit: 0,
156 khtml: 0,
157 opera: 0,
158
159 //complete version
160 ver: null
161 };
162
163 // 浏览器
164 var browser = {
165 //browsers
166 ie: 0,
167 firefox: 0,
168 safari: 0,
169 konq: 0,
170 opera: 0,
171 chrome: 0,
172 //specific version
173 ver: null
174 };
175
176 // 客户端平台platform/device/OS
177 var system = {
178 win: false,
179 mac: false,
180 x11: false,
181
182 //移动设备
183 iphone: false,
184 ipod: false,
185 ipad: false,
186 ios: false,
187 android: false,
188 nokiaN: false,
189 winMobile: false,
190
191 //game systems
192 wii: false,
193 ps: false
194 };
195
196 // 检测浏览器引擎
197 var ua = navigator.userAgent;
198 if (window.opera){
199 engine.ver = browser.ver = window.opera.version();
200 engine.opera = browser.opera = parseFloat(engine.ver);
201 } else if (/AppleWebKit\/(\S+)/.test(ua)){
202 engine.ver = RegExp["$1"];
203 engine.webkit = parseFloat(engine.ver);
204
205 //figure out if it's Chrome or Safari
206 if (/Chrome\/(\S+)/.test(ua)){
207 browser.ver = RegExp["$1"];
208 browser.chrome = parseFloat(browser.ver);
209 } else if (/Version\/(\S+)/.test(ua)){
210 browser.ver = RegExp["$1"];
211 browser.safari = parseFloat(browser.ver);
212 } else {
213 //approximate version
214 var safariVersion = 1;
215 if (engine.webkit < 100){
216 safariVersion = 1;
217 } else if (engine.webkit < 312){
218 safariVersion = 1.2;
219 } else if (engine.webkit < 412){
220 safariVersion = 1.3;
221 } else {
222 safariVersion = 2;
223 }
224
225 browser.safari = browser.ver = safariVersion;
226 }
227 } else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){
228 engine.ver = browser.ver = RegExp["$1"];
229 engine.khtml = browser.konq = parseFloat(engine.ver);
230 } else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){
231 engine.ver = RegExp["$1"];
232 engine.gecko = parseFloat(engine.ver);
233
234 //determine if it's Firefox
235 if (/Firefox\/(\S+)/.test(ua)){
236 browser.ver = RegExp["$1"];
237 browser.firefox = parseFloat(browser.ver);
238 }
239 } else if (/MSIE ([^;]+)/.test(ua)){
240 engine.ver = browser.ver = RegExp["$1"];
241 engine.ie = browser.ie = parseFloat(engine.ver);
242 }
243
244 //detect browsers
245 browser.ie = engine.ie;
246 browser.opera = engine.opera;
247
248
249 //detect platform
250 var p = navigator.platform;
251 system.win = p.indexOf("Win") == 0;
252 system.mac = p.indexOf("Mac") == 0;
253 system.x11 = (p == "X11") || (p.indexOf("Linux") == 0);
254
255 //detect windows operating systems
256 if (system.win){
257 if (/Win(?:dows )?([^do]{2})\s?(\d+\.\d+)?/.test(ua)){
258 if (RegExp["$1"] == "NT"){
259 switch(RegExp["$2"]){
260 case "5.0":
261 system.win = "2000";
262 break;
263 case "5.1":
264 system.win = "XP";
265 break;
266 case "6.0":
267 system.win = "Vista";
268 break;
269 case "6.1":
270 system.win = "7";
271 break;
272 default:
273 system.win = "NT";
274 break;
275 }
276 } else if (RegExp["$1"] == "9x"){
277 system.win = "ME";
278 } else {
279 system.win = RegExp["$1"];
280 }
281 }
282 }
283
284 //mobile devices
285 system.iphone = ua.indexOf("iPhone") > -1;
286 system.ipod = ua.indexOf("iPod") > -1;
287 system.ipad = ua.indexOf("iPad") > -1;
288 system.nokiaN = ua.indexOf("NokiaN") > -1;
289
290 //windows mobile
291 if (system.win == "CE"){
292 system.winMobile = system.win;
293 } else if (system.win == "Ph"){
294 if(/Windows Phone OS (\d+.\d+)/.test(ua)){;
295 system.win = "Phone";
296 system.winMobile = parseFloat(RegExp["$1"]);
297 }
298 }
299
300 //determine iOS version
301 if (system.mac && ua.indexOf("Mobile") > -1){
302 if (/CPU (?:iPhone )?OS (\d+_\d+)/.test(ua)){
303 system.ios = parseFloat(RegExp.$1.replace("_", "."));
304 } else {
305 system.ios = 2; //can't really detect - so guess
306 }
307 }
308
309 //determine Android version
310 if (/Android (\d+\.\d+)/.test(ua)){
311 system.android = parseFloat(RegExp.$1);
312 }
313
314 //gaming systems
315 system.wii = ua.indexOf("Wii") > -1;
316 system.ps = /playstation/i.test(ua);
317
318 //return it
319 return {
320 engine: engine,
321 browser: browser,
322 system: system
323 };
324
325 }(),
326 /**
327 *Tween 缓动相关
328 */
329 tween: {
330 Linear: function(t, b, c, d) {
331 return c * t / d + b;
332 },
333 Quad: {
334 easeIn: function(t, b, c, d) {
335 return c * (t /= d) * t + b;
336 },
337 easeOut: function(t, b, c, d) {
338 return - c * (t /= d) * (t - 2) + b;
339 },
340 easeInOut: function(t, b, c, d) {
341 if ((t /= d / 2) < 1) return c / 2 * t * t + b;
342 return - c / 2 * ((--t) * (t - 2) - 1) + b;
343 }
344 },
345 Cubic: {
346 easeIn: function(t, b, c, d) {
347 return c * (t /= d) * t * t + b;
348 },
349 easeOut: function(t, b, c, d) {
350 return c * ((t = t / d - 1) * t * t + 1) + b;
351 },
352 easeInOut: function(t, b, c, d) {
353 if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
354 return c / 2 * ((t -= 2) * t * t + 2) + b;
355 }
356 },
357 Quart: {
358 easeIn: function(t, b, c, d) {
359 return c * (t /= d) * t * t * t + b;
360 },
361 easeOut: function(t, b, c, d) {
362 return - c * ((t = t / d - 1) * t * t * t - 1) + b;
363 },
364 easeInOut: function(t, b, c, d) {
365 if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
366 return - c / 2 * ((t -= 2) * t * t * t - 2) + b;
367 }
368 },
369 Quint: {
370 easeIn: function(t, b, c, d) {
371 return c * (t /= d) * t * t * t * t + b;
372 },
373 easeOut: function(t, b, c, d) {
374 return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
375 },
376 easeInOut: function(t, b, c, d) {
377 if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
378 return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
379 }
380 },
381 Sine: {
382 easeIn: function(t, b, c, d) {
383 return - c * Math.cos(t / d * (Math.PI / 2)) + c + b;
384 },
385 easeOut: function(t, b, c, d) {
386 return c * Math.sin(t / d * (Math.PI / 2)) + b;
387 },
388 easeInOut: function(t, b, c, d) {
389 return - c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
390 }
391 },
392 Expo: {
393 easeIn: function(t, b, c, d) {
394 return (t == 0) ? b: c * Math.pow(2, 10 * (t / d - 1)) + b;
395 },
396 easeOut: function(t, b, c, d) {
397 return (t == d) ? b + c: c * ( - Math.pow(2, -10 * t / d) + 1) + b;
398 },
399 easeInOut: function(t, b, c, d) {
400 if (t == 0) return b;
401 if (t == d) return b + c;
402 if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
403 return c / 2 * ( - Math.pow(2, -10 * --t) + 2) + b;
404 }
405 },
406 Circ: {
407 easeIn: function(t, b, c, d) {
408 return - c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
409 },
410 easeOut: function(t, b, c, d) {
411 return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
412 },
413 easeInOut: function(t, b, c, d) {
414 if ((t /= d / 2) < 1) return - c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
415 return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
416 }
417 },
418 Elastic: {
419 easeIn: function(t, b, c, d, a, p) {
420 if (t == 0) return b;
421 if ((t /= d) == 1) return b + c;
422 if (!p) p = d * .3;
423 if (!a || a < Math.abs(c)) {
424 a = c;
425 var s = p / 4;
426 } else var s = p / (2 * Math.PI) * Math.asin(c / a);
427 return - (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
428 },
429 easeOut: function(t, b, c, d, a, p) {
430 if (t == 0) return b;
431 if ((t /= d) == 1) return b + c;
432 if (!p) p = d * .3;
433 if (!a || a < Math.abs(c)) {
434 a = c;
435 var s = p / 4;
436 } else var s = p / (2 * Math.PI) * Math.asin(c / a);
437 return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b);
438 },
439 easeInOut: function(t, b, c, d, a, p) {
440 if (t == 0) return b;
441 if ((t /= d / 2) == 2) return b + c;
442 if (!p) p = d * (.3 * 1.5);
443 if (!a || a < Math.abs(c)) {
444 a = c;
445 var s = p / 4;
446 } else var s = p / (2 * Math.PI) * Math.asin(c / a);
447 if (t < 1) return - .5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
448 return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
449 }
450 },
451 Back: {
452 easeIn: function(t, b, c, d, s) {
453 if (s == undefined) s = 1.70158;
454 return c * (t /= d) * t * ((s + 1) * t - s) + b;
455 },
456 easeOut: function(t, b, c, d, s) {
457 if (s == undefined) s = 1.70158;
458 return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
459 },
460 easeInOut: function(t, b, c, d, s) {
461 if (s == undefined) s = 1.70158;
462 if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
463 return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
464 }
465 },
466 Bounce: {
467 easeIn: function(t, b, c, d) {
468 return c - Tween.Bounce.easeOut(d - t, 0, c, d) + b;
469 },
470 easeOut: function(t, b, c, d) {
471 if ((t /= d) < (1 / 2.75)) {
472 return c * (7.5625 * t * t) + b;
473 } else if (t < (2 / 2.75)) {
474 return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
475 } else if (t < (2.5 / 2.75)) {
476 return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
477 } else {
478 return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
479 }
480 },
481 easeInOut: function(t, b, c, d) {
482 if (t < d / 2) return Tween.Bounce.easeIn(t * 2, 0, c, d) * .5 + b;
483 else return Tween.Bounce.easeOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
484 }
485 }
486 }
487
488 }