![]()
1 //前台调用
2 var $ = function (args) {
3 return new Base(args);
4 }
5
6 //基础库
7 function Base(args) {
8 //创建一个数组,来保存获取的节点和节点数组
9 this.elements = [];
10
11 if (typeof args == 'string') {
12 //css模拟
13 if (args.indexOf(' ') != -1) {
14 var elements = args.split(' '); //把节点拆开分别保存到数组里
15 var childElements = []; //存放临时节点对象的数组,解决被覆盖的问题
16 var node = []; //用来存放父节点用的
17 for (var i = 0; i < elements.length; i ++) {
18 if (node.length == 0) node.push(document); //如果默认没有父节点,就把document放入
19 switch (elements[i].charAt(0)) {
20 case '#' :
21 childElements = []; //清理掉临时节点,以便父节点失效,子节点有效
22 childElements.push(this.getId(elements[i].substring(1)));
23 node = childElements; //保存父节点,因为childElements要清理,所以需要创建node数组
24 break;
25 case '.' :
26 childElements = [];
27 for (var j = 0; j < node.length; j ++) {
28 var temps = this.getClass(elements[i].substring(1), node[j]);
29 for (var k = 0; k < temps.length; k ++) {
30 childElements.push(temps[k]);
31 }
32 }
33 node = childElements;
34 break;
35 default :
36 childElements = [];
37 for (var j = 0; j < node.length; j ++) {
38 var temps = this.getTagName(elements[i], node[j]);
39 for (var k = 0; k < temps.length; k ++) {
40 childElements.push(temps[k]);
41 }
42 }
43 node = childElements;
44 }
45 }
46 this.elements = childElements;
47 } else {
48 //find模拟
49 switch (args.charAt(0)) {
50 case '#' :
51 this.elements.push(this.getId(args.substring(1)));
52 break;
53 case '.' :
54 this.elements = this.getClass(args.substring(1));
55 break;
56 default :
57 this.elements = this.getTagName(args);
58 }
59 }
60 } else if (typeof args == 'object') {
61 if (args != undefined) { //_this是一个对象,undefined也是一个对象,区别与typeof返回的带单引号的'undefined'
62 this.elements[0] = args;
63 }
64 } else if (typeof args == 'function') {
65 this.ready(args);
66 }
67 }
68
69 //addDomLoaded
70 Base.prototype.ready = function (fn) {
71 addDomLoaded(fn);
72 };
73
74 //获取ID节点
75 Base.prototype.getId = function (id) {
76 return document.getElementById(id)
77 };
78
79 //获取元素节点数组
80 Base.prototype.getTagName = function (tag, parentNode) {
81 var node = null;
82 var temps = [];
83 if (parentNode != undefined) {
84 node = parentNode;
85 } else {
86 node = document;
87 }
88 var tags = node.getElementsByTagName(tag);
89 for (var i = 0; i < tags.length; i ++) {
90 temps.push(tags[i]);
91 }
92 return temps;
93 };
94
95 //获取CLASS节点数组
96 Base.prototype.getClass = function (className, parentNode) {
97 var node = null;
98 var temps = [];
99 if (parentNode != undefined) {
100 node = parentNode;
101 } else {
102 node = document;
103 }
104 var all = node.getElementsByTagName('*');
105 for (var i = 0; i < all.length; i ++) {
106 if ((new RegExp('(\\s|^)' +className +'(\\s|$)')).test(all[i].className)) {
107 temps.push(all[i]);
108 }
109 }
110 return temps;
111 }
112
113 //设置CSS选择器子节点
114 Base.prototype.find = function (str) {
115 var childElements = [];
116 for (var i = 0; i < this.elements.length; i ++) {
117 switch (str.charAt(0)) {
118 case '#' :
119 childElements.push(this.getId(str.substring(1)));
120 break;
121 case '.' :
122 var temps = this.getClass(str.substring(1), this.elements[i]);
123 for (var j = 0; j < temps.length; j ++) {
124 childElements.push(temps[j]);
125 }
126 break;
127 default :
128 var temps = this.getTagName(str, this.elements[i]);
129 for (var j = 0; j < temps.length; j ++) {
130 childElements.push(temps[j]);
131 }
132 }
133 }
134 this.elements = childElements;
135 return this;
136 }
137
138 //获取某一个节点,并返回这个节点对象
139 Base.prototype.ge = function (num) {
140 return this.elements[num];
141 };
142
143 //获取首个节点,并返回这个节点对象
144 Base.prototype.first = function () {
145 return this.elements[0];
146 };
147
148 //获取末个节点,并返回这个节点对象
149 Base.prototype.last = function () {
150 return this.elements[this.elements.length - 1];
151 };
152
153 //获取某组节点的数量
154 Base.prototype.length = function () {
155 return this.elements.length;
156 };
157
158 //获取某一个节点的属性
159 Base.prototype.attr = function (attr, value) {
160 for (var i = 0; i < this.elements.length; i ++) {
161 if (arguments.length == 1) {
162 return this.elements[i].getAttribute(attr);
163 } else if (arguments.length == 2) {
164 this.elements[i].setAttribute(attr, value);
165 }
166 }
167 return this;
168 };
169
170 //获取某一个节点在整个节点组中是第几个索引
171 Base.prototype.index = function () {
172 var children = this.elements[0].parentNode.children;
173 for (var i = 0; i < children.length; i ++) {
174 if (this.elements[0] == children[i]) return i;
175 }
176 };
177
178 //设置某一个节点的透明度
179 Base.prototype.opacity = function (num) {
180 for (var i = 0; i < this.elements.length; i ++) {
181 this.elements[i].style.opacity = num / 100;
182 this.elements[i].style.filter = 'alpha(opacity=' + num + ')';
183 }
184 return this;
185 };
186
187 //获取某一个节点,并且Base对象
188 Base.prototype.eq = function (num) {
189 var element = this.elements[num];
190 this.elements = [];
191 this.elements[0] = element;
192 return this;
193 };
194
195 //获取当前节点的下一个元素节点
196 Base.prototype.next = function () {
197 for (var i = 0; i < this.elements.length; i ++) {
198 this.elements[i] = this.elements[i].nextSibling;
199 if (this.elements[i] == null) throw new Error('找不到下一个同级元素节点!');
200 if (this.elements[i].nodeType == 3) this.next();
201 }
202 return this;
203 };
204
205 //获取当前节点的上一个元素节点
206 Base.prototype.prev = function () {
207 for (var i = 0; i < this.elements.length; i ++) {
208 this.elements[i] = this.elements[i].previousSibling;
209 if (this.elements[i] == null) throw new Error('找不到上一个同级元素节点!');
210 if (this.elements[i].nodeType == 3) this.prev();
211 }
212 return this;
213 };
214
215 //设置CSS
216 Base.prototype.css = function (attr, value) {
217 for (var i = 0; i < this.elements.length; i ++) {
218 if (arguments.length == 1) {
219 return getStyle(this.elements[i], attr);
220 }
221 this.elements[i].style[attr] = value;
222 }
223 return this;
224 }
225
226 //添加Class
227 Base.prototype.addClass = function (className) {
228 for (var i = 0; i < this.elements.length; i ++) {
229 if (!hasClass(this.elements[i], className)) {
230 this.elements[i].className += ' ' + className;
231 }
232 }
233 return this;
234 }
235
236 //移除Class
237 Base.prototype.removeClass = function (className) {
238 for (var i = 0; i < this.elements.length; i ++) {
239 if (hasClass(this.elements[i], className)) {
240 this.elements[i].className = this.elements[i].className.replace(new RegExp('(\\s|^)' +className +'(\\s|$)'), ' ');
241 }
242 }
243 return this;
244 }
245
246 //添加link或style的CSS规则
247 Base.prototype.addRule = function (num, selectorText, cssText, position) {
248 var sheet = document.styleSheets[num];
249 insertRule(sheet, selectorText, cssText, position);
250 return this;
251 }
252
253 //移除link或style的CSS规则
254 Base.prototype.removeRule = function (num, index) {
255 var sheet = document.styleSheets[num];
256 deleteRule(sheet, index);
257 return this;
258 }
259
260 //设置表单字段元素
261 Base.prototype.form = function (name) {
262 for (var i = 0; i < this.elements.length; i ++) {
263 this.elements[i] = this.elements[i][name];
264 }
265 return this;
266 };
267
268 //设置表单字段内容获取
269 Base.prototype.value = function (str) {
270 for (var i = 0; i < this.elements.length; i ++) {
271 if (arguments.length == 0) {
272 return this.elements[i].value;
273 }
274 this.elements[i].value = str;
275 }
276 return this;
277 }
278
279 //设置innerHTML
280 Base.prototype.html = function (str) {
281 for (var i = 0; i < this.elements.length; i ++) {
282 if (arguments.length == 0) {
283 return this.elements[i].innerHTML;
284 }
285 this.elements[i].innerHTML = str;
286 }
287 return this;
288 }
289
290 //设置innerText
291 Base.prototype.text = function (str) {
292 for (var i = 0; i < this.elements.length; i ++) {
293 if (arguments.length == 0) {
294 return getInnerText(this.elements[i]);
295 }
296 setInnerText(this.elements[i], text);
297 }
298 return this;
299 }
300
301 //设置事件发生器
302 Base.prototype.bind = function (event, fn) {
303 for (var i = 0; i < this.elements.length; i ++) {
304 addEvent(this.elements[i], event, fn);
305 }
306 return this;
307 };
308
309 //设置鼠标移入移出方法
310 Base.prototype.hover = function (over, out) {
311 for (var i = 0; i < this.elements.length; i ++) {
312 addEvent(this.elements[i], 'mouseover', over);
313 addEvent(this.elements[i], 'mouseout', out);
314 }
315 return this;
316 };
317
318 //设置点击切换方法
319 Base.prototype.toggle = function () {
320 for (var i = 0; i < this.elements.length; i ++) {
321 (function (element, args) {
322 var count = 0;
323 addEvent(element, 'click', function () {
324 args[count++ % args.length].call(this);
325 });
326 })(this.elements[i], arguments);
327 }
328 return this;
329 };
330
331 //设置显示
332 Base.prototype.show = function () {
333 for (var i = 0; i < this.elements.length; i ++) {
334 this.elements[i].style.display = 'block';
335 }
336 return this;
337 };
338
339 //设置隐藏
340 Base.prototype.hide = function () {
341 for (var i = 0; i < this.elements.length; i ++) {
342 this.elements[i].style.display = 'none';
343 }
344 return this;
345 };
346
347 //设置物体居中
348 Base.prototype.center = function (width, height) {
349 var top = (getInner().height - height) / 2 + getScroll().top;
350 var left = (getInner().width - width) / 2 + getScroll().left;
351 for (var i = 0; i < this.elements.length; i ++) {
352 this.elements[i].style.top = top + 'px';
353 this.elements[i].style.left = left + 'px';
354 }
355 return this;
356 };
357
358 //锁屏功能
359 Base.prototype.lock = function () {
360 for (var i = 0; i < this.elements.length; i ++) {
361 fixedScroll.top = getScroll().top;
362 fixedScroll.left = getScroll().left;
363 this.elements[i].style.width = getInner().width + getScroll().left + 'px';
364 this.elements[i].style.height = getInner().height + getScroll().top + 'px';
365 this.elements[i].style.display = 'block';
366 parseFloat(sys.firefox) < 4 ? document.body.style.overflow = 'hidden' : document.documentElement.style.overflow = 'hidden';
367 addEvent(this.elements[i], 'mousedown', predef);
368 addEvent(this.elements[i], 'mouseup', predef);
369 addEvent(this.elements[i], 'selectstart', predef);
370 addEvent(window, 'scroll', fixedScroll);
371 }
372 return this;
373 };
374
375 Base.prototype.unlock = function () {
376 for (var i = 0; i < this.elements.length; i ++) {
377 this.elements[i].style.display = 'none';
378 parseFloat(sys.firefox) < 4 ? document.body.style.overflow = 'auto' : document.documentElement.style.overflow = 'auto';
379 removeEvent(this.elements[i], 'mousedown', predef);
380 removeEvent(this.elements[i], 'mouseup', predef);
381 removeEvent(this.elements[i], 'selectstart', predef);
382 removeEvent(window, 'scroll', fixedScroll);
383 }
384 return this;
385 };
386
387 //触发点击事件
388 Base.prototype.click = function (fn) {
389 for (var i = 0; i < this.elements.length; i ++) {
390 this.elements[i].onclick = fn;
391 }
392 return this;
393 };
394
395 //触发浏览器窗口事件
396 Base.prototype.resize = function (fn) {
397 for (var i = 0; i < this.elements.length; i ++) {
398 var element = this.elements[i];
399 addEvent(window, 'resize', function () {
400 fn();
401 if (element.offsetLeft > getInner().width + getScroll().left - element.offsetWidth) {
402 element.style.left = getInner().width + getScroll().left - element.offsetWidth + 'px';
403 if (element.offsetLeft <= 0 + getScroll().left) {
404 element.style.left = 0 + getScroll().left + 'px';
405 }
406 }
407 if(element.offsetTop > getInner().height + getScroll().top - element.offsetHeight) {
408 element.style.top = getInner().height + getScroll().top - element.offsetHeight + 'px';
409 if (element.offsetTop <= 0 + getScroll().top) {
410 element.style.top = 0 + getScroll().top + 'px';
411 }
412 }
413 });
414 }
415 return this;
416 };
417
418 //设置动画
419 Base.prototype.animate = function (obj) {
420 for (var i = 0; i < this.elements.length; i ++) {
421 var element = this.elements[i];
422 var attr = obj['attr'] == 'x' ? 'left' : obj['attr'] == 'y' ? 'top' :
423 obj['attr'] == 'w' ? 'width' : obj['attr'] == 'h' ? 'height' :
424 obj['attr'] == 'o' ? 'opacity' : obj['attr'] != undefined ? obj['attr'] : 'left';
425
426
427 var start = obj['start'] != undefined ? obj['start'] :
428 attr == 'opacity' ? parseFloat(getStyle(element, attr)) * 100 :
429 parseInt(getStyle(element, attr));
430
431 var t = obj['t'] != undefined ? obj['t'] : 10; //可选,默认10毫秒执行一次
432 var step = obj['step'] != undefined ? obj['step'] : 20; //可选,每次运行10像素
433
434 var alter = obj['alter'];
435 var target = obj['target'];
436 var mul = obj['mul'];
437
438 var speed = obj['speed'] != undefined ? obj['speed'] : 6; //可选,默认缓冲速度为6
439 var type = obj['type'] == 0 ? 'constant' : obj['type'] == 1 ? 'buffer' : 'buffer'; //可选,0表示匀速,1表示缓冲,默认缓冲
440
441
442 if (alter != undefined && target == undefined) {
443 target = alter + start;
444 } else if (alter == undefined && target == undefined && mul == undefined) {
445 throw new Error('alter增量或target目标量必须传一个!');
446 }
447
448
449
450 if (start > target) step = -step;
451
452 if (attr == 'opacity') {
453 element.style.opacity = parseInt(start) / 100;
454 element.style.filter = 'alpha(opacity=' + parseInt(start) +')';
455 } else {
456 //element.style[attr] = start + 'px';
457 }
458
459
460 if (mul == undefined) {
461 mul = {};
462 mul[attr] = target;
463 }
464
465
466 clearInterval(element.timer);
467 element.timer = setInterval(function () {
468
469 /*
470 问题1:多个动画执行了多个列队动画,我们要求不管多少个动画只执行一个列队动画
471 问题2:多个动画数值差别太大,导致动画无法执行到目标值,原因是定时器提前清理掉了
472
473 解决1:不管多少个动画,只提供一次列队动画的机会
474 解决2:多个动画按最后一个分动画执行完毕后再清理即可
475 */
476
477 //创建一个布尔值,这个值可以了解多个动画是否全部执行完毕
478 var flag = true; //表示都执行完毕了
479
480
481 for (var i in mul) {
482 attr = i == 'x' ? 'left' : i == 'y' ? 'top' : i == 'w' ? 'width' : i == 'h' ? 'height' : i == 'o' ? 'opacity' : i != undefined ? i : 'left';
483 target = mul[i];
484
485
486 if (type == 'buffer') {
487 step = attr == 'opacity' ? (target - parseFloat(getStyle(element, attr)) * 100) / speed :
488 (target - parseInt(getStyle(element, attr))) / speed;
489 step = step > 0 ? Math.ceil(step) : Math.floor(step);
490 }
491
492
493
494 if (attr == 'opacity') {
495 if (step == 0) {
496 setOpacity();
497 } else if (step > 0 && Math.abs(parseFloat(getStyle(element, attr)) * 100 - target) <= step) {
498 setOpacity();
499 } else if (step < 0 && (parseFloat(getStyle(element, attr)) * 100 - target) <= Math.abs(step)) {
500 setOpacity();
501 } else {
502 var temp = parseFloat(getStyle(element, attr)) * 100;
503 element.style.opacity = parseInt(temp + step) / 100;
504 element.style.filter = 'alpha(opacity=' + parseInt(temp + step) + ')';
505 }
506
507 if (parseInt(target) != parseInt(parseFloat(getStyle(element, attr)) * 100)) flag = false;
508
509 } else {
510 if (step == 0) {
511 setTarget();
512 } else if (step > 0 && Math.abs(parseInt(getStyle(element, attr)) - target) <= step) {
513 setTarget();
514 } else if (step < 0 && (parseInt(getStyle(element, attr)) - target) <= Math.abs(step)) {
515 setTarget();
516 } else {
517 element.style[attr] = parseInt(getStyle(element, attr)) + step + 'px';
518 }
519
520 if (parseInt(target) != parseInt(getStyle(element, attr))) flag = false;
521 }
522
523 //document.getElementById('test').innerHTML += i + '--' + parseInt(target) + '--' + parseInt(getStyle(element, attr)) + '--' + flag + '<br />';
524
525 }
526
527 if (flag) {
528 clearInterval(element.timer);
529 if (obj.fn != undefined) obj.fn();
530 }
531
532 }, t);
533
534 function setTarget() {
535 element.style[attr] = target + 'px';
536 }
537
538 function setOpacity() {
539 element.style.opacity = parseInt(target) / 100;
540 element.style.filter = 'alpha(opacity=' + parseInt(target) + ')';
541 }
542 }
543 return this;
544 };
545
546 //插件入口
547 Base.prototype.extend = function (name, fn) {
548 Base.prototype[name] = fn;
549 };