jQuery函数的封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
<script>
//首先封装对象的获取方法
function getEles(arg){
//用正则判断开头和结尾是否一个或有多个空格
var reg1 = /^\s*|\s*$/g;
arg = arg.replace(reg1,"");
//用正则判断中间是否有空格,假如有替换成一个空格
var reg2 = /\s+/g;
arg = arg.replace(reg2," ");
//将arg通过空格来分割成需要的数组
var elArr = arg.split(" ");
var result = [];
var parents = [document];
//对arg进行遍历,找到选中的arg
for(var i=0;i<elArr.length;i++){
result = [];
for(var j=0;j<parents.length;j++){
//通过if分别判断需要使用id、class或者tagName选择器
if(/^#/.test(elArr[i])){
//通过字符串截取,去掉单词开头的#号
var idName = elArr[i].substring(1);
//找到对应的对象,并将其推入数组
var idArr = document.getElementById(idName);
result.push(idArr);
}else if(/^\./.test(elArr[i])){
var className = elArr[i].slice(1);
var classArr = findClass(parents[j],className);
for(var k=0;k<classArr.length;k++){
result.push(classArr[k]);
}
}else{
var tagArr = parents[j].getElementsByTagName(elArr[i]);
for(var k=0;k<tagArr.length;k++){
result.push(tagArr[k]);
}
}
}
parents = result;
}
return parents;
}
//封装获取class,主要因为需要兼容IE浏览器
function findClass(obj,className){
if(window.getElementsByClassName){
return obj.getElementsByClassName(className);
}else{
//因为IE支持tagName选择器,所以首先找到obj下的所有标签,然后通过正则来找到需要的className
var tagArr = obj.getElementsByTagName("*");
var classArr = [];
var reg = new RegExp("\\b"+className+"\\b");
for(var k=0;k<tagArr.length;k++){
if(reg.test(tagArr[k].className)){
classArr.push(tagArr[k]);
}
}
return classArr;
}
}

//jQuery标志为$,所以封装函数来模拟
function $(arg){
return new Jq(arg);
}

//创建构造函数Jq
function Jq(arg){
//通过创建一个数组来记录选择到的对象
this.elements = [];
//因$(arg)能传三种形式,所以对其进行判断
if(typeof(arg) == "function"){
ready(arg);
}else if(typeof(arg) == "string"){
this.elements = getEles(arg);
}else{
this.elements.push(arg);
}
}
//因Jq(function)的函数是在html、css和js都加载完成时才运行的,所以需要对其进行判断
function ready(fn){
if(window.addEventListener){
document.addEventListener("DOMContentLoaded",fn,false);
}else{
var oS = document.createElement("script");
oS.defer = true;
var oH = document.getElementsByTagName("head")[0];
oH.appendChild(oS);
oS.onreadystatechange = function(){
if(oS.readyState == "complete"){
fn();
}
}
}
}

//对其原型设置click方法,模拟jQuery的click()方法
Jq.prototype.click = function(fn){
for(var i=0;i<this.elements.length;i++){
addEvent("click",fn,this.elements[i]);
}
}
//因添加click时,需要涉及到IE的兼容,所以封装一个函数
function addEvent(event,fn,obj){
if(obj.addEventListener){
obj.addEventListener(event,fn,false);
}else{
obj.attachEvent("on"+event,fn);
}
}

//对其原型设置on方法,模拟jQuery的on()方法
Jq.prototype.on = function(event,fn){
//因有可能会设置"click mouseleave"等多事件,所以将其分成数组
var eventArr = event.split(" ");
for(var i=0;i<this.elements.length;i++){
for(var j=0;j<eventArr.length;j++){
addEvent(eventArr[j],fn,this.elements[i]);
}
}
}

//对其原型设置.css方法,模拟jQuery的css()方法
Jq.prototype.css = function(){
//因css(arg)有三种情况,所以对其分别设置
if(arguments.length == 1){
if(typeof(arguments[0]) == "string"){
//当只有一个属性时,是获取属性值,需要返回出去
return getStyle(this.elements[0],arguments[0]);
}else{
//当其为JSON数据时,就是设置
for(var i=0;i<this.elements.length;i++){
//通过使用for in循环来获得JSON的内容
for(var keys in arguments[0]){
setStyle(this.elements[i],keys,arguments[0][keys]);
}
}
}
}else if(arguments.length == 2){
for(var i=0;i<this.elements.length;i++){
setStyle(this.elements[i],arguments[0],arguments[1]);
}
}
}
//因需兼容IE浏览器,所以封装getStyle函数
function getStyle(obj,style){
if(window.getComputedStyle){
return getComputedStyle(obj,null)[style];
}else{
return obj.currentStyle(style);
}
}
//因需兼容IE浏览器,所以封装setStyle函数
function setStyle(obj,styleName,styleValue){
//因jQuery中width、height、left、top仅写数字时也是生效的,所以需要加个判断
var selectArr = ["width","height","left","top"];
for(var i=0;i<selectArr.length;i++){
if(selectArr[i] == styleName){
if(typeof(styleValue) == "number"){
styleValue = styleValue + "px";
}
}
}
obj.style[styleName] = styleValue;
}

//对原型设置eq()的方法
Jq.prototype.eq = function(index){
return new Jq(this.elements[index]);
}
</script>