jQuery学习之路(7)- 用原生JavaScript实现jQuery的某些简单功能

2016-12-19 19:56:10来源:cnblogs.com作者:用原生JavaScript实现jQuery的某些简单功能 -人点击

第七城市

▓▓▓▓▓▓ 大致介绍

    学习了妙味,用原生的JavaScript实现jQuery中的某些部分功能

    定义自己的函数库lQuery

 

▓▓▓▓▓▓ $()选择器的实现

    jQuery是面向对象的,所以自己编写的也要是面向对象的,看看基本的结构

 1 // 定义lQuery对象 2 function lQuery(lArg){ 3  4  5 } 6  7 function lQ(lArg){ 8     return new lQuery(lArg); 9 10 }11 12 // css()方法13 lQuery.prototype.css = function(){};14 15 // html()方法16 lQuery.prototype.html = function(){};

 

    先来仿写jQuery中的$(函数)的方法

 1 // 定义lQuery对象 2 function lQuery(lArg){ 3  4     // 用typeof判断参数的类型是 function 、 5     switch( typeof lArg){ 6         case 'function': 7             //  如果采用这种写法,给lQ绑定相同的函数,但是只会执行一次 8             // window.onload = lArg; 9             // break;10     }11 12 }

    如果写出这样的函数就会出现问题

 1         lQ(function(){ 2  3             alert(1); 4  5         }); 6         lQ(function(){ 7  8             alert(2); 9 10         });

    这样就只会弹出'2',但是在jQuery中都会弹出,所以上面的方法不对,我们采用事件绑定的形式来解决这个问题

 1 // 绑定事件函数 2 function lQbind(obj,eventName,fn){ 3     // 标准浏览器 4     if(obj.addEventListener){ 5         obj.addEventListener(eventName,fn,false); 6     }else{ 7         // IE浏览器 8         obj.attachEvent('on'+eventName,fn); 9     }10 }

    可以使用这样调用

1     switch( typeof lArg){2         case 'function':3             //  如果采用这种写法,给lQ绑定相同的函数,但是只会执行一次4             // window.onload = lArg;5             // break;6             lQbind(window,'load',lArg);7             break;8     }

 

    仿写jQuery中的$('.div')、$('#div')、$('div')三种方法

    这三种方法的区别是第一个字符的不同,所以我们可以根据第一个字符的不同来进行区别对待

    先来仿写$('.div')

1                     // '.div'2                 case '.':3                     this.elements = getClass(document,lArg.substring(1));4                     break;

 

    由于getElementsByClassName()是HTML5里的方法,像IE8以下不兼容所以我们自己写了一个简单的getClass方法

 1 // 获取class属性 2 function getClass(obj,name){ 3     var arr = []; 4     var elems = obj.getElementsByTagName('*'); 5     for(var i=0;i<elems.length;i++){ 6         if(elems[i].className == name){ 7             arr.push(elems[i]); 8         } 9     }10     return arr;11 }

 

    仿写$('#div')

1                 case '#':2                     this.elements.push(document.getElementById(lArg.substring(1)));3                     break;4                     // '.div'5                 case '.':

 

    仿写$('div')

1                 default:2                     // getElementsByTagName返回的是一个类数组NodeList,为了防止以后出现麻烦,要把他转为一个3                     // 数组4                     this.elements = toArray(document.getElementsByTagName(lArg));5                     break;

    由于getElementsByTagName返回的是一个类数组NodeList,为了防止以后出现麻烦,要把他转为一个数组,自定义了一个toArray方法

1 // 将一个类数组转为真正的数组2 function toArray(lickArr){3     var arr = [];4     for(var i=0;i<lickArr.length;i++){5         arr.push(lickArr[i]);6     }7     return arr;8 }

 

    仿写$(对象)的方法

1         // window  document2         case 'object':3             this.elements.push(lArg);4             break;

 

▓▓▓▓▓▓ html()的实现

    html()方法分为有参和无参

 1 // html()方法 2 lQuery.prototype.html = function(str){ 3  4     if(str){  //设置 5         for(var i=0;i<this.elements.length;i++){ 6             this.elements[i].innerHTML = str; 7         } 8     }else{ 9         return this.elements[0].innerHTML;10     }11     return this;12     13 };

 

▓▓▓▓▓▓ on()方法的实现

    利用前面实现的绑定函数可以很容易的实现

1 lQuery.prototype.on = function(eventName,fn){2     for(var i=0;i<this.elements.length;i++){3         lQbind(this.elements[i],eventName,fn);4     }5 }

 

▓▓▓▓▓▓ click()和mouseover()方法的实现

  利用on()方法可以容易的实现

 1 // click()方法 2 lQuery.prototype.click = function(fn){ 3     this.on('click',fn); 4     return this; 5 } 6  7 // mouseover()方法 8 lQuery.prototype.mouseover = function(fn){ 9     this.on('mouseover',fn);10     return this;11 }

 

▓▓▓▓▓▓ hide()和show()方法的实现

 1 // hide()方法 2 lQuery.prototype.hide = function(){ 3  4     for(var i=0;i<this.elements.length;i++){ 5         this.elements[i].style.display = 'none'; 6     } 7     return this; 8 } 9 10 // show()方法11 lQuery.prototype.show = function(){12 13     for(var i=0;i<this.elements.length;i++){14         this.elements[i].style.display = 'block';15     }16     return this;17 }

 

 

▓▓▓▓▓▓ hover()方法的实现

1 // hover()方法2 lQuery.prototype.hover = function(fnover,fnout){3     this.on('mouseover',fnover);4     this.on('mouseout',fnout);5     return this;6 }

 

▓▓▓▓▓▓ css()方法的实现

    实现$('div').css('width')和$('div').css('width','200px')

 1 lQuery.prototype.css = function(attr,value){ 2     if(arguments.length == 2){ 3         for(var i=0;i<this.elements.length;i++){ 4             this.elements[i].attr = value; 5         } 6     } 7  8     if(arguments.length == 1){ 9         return getStyle(this.elements[0],attr);10     }11 }

    定义了getStyle()方法是为了能找到行内样式以外的样式

1 // 获取属性2 function getStyle(obj,attr){3     if(obj.currentStyle[attr]){4         obj.currentStyle[attr];5     }else{6         obj.getComputedStyle(obj,false)[attr];7     }8 }

 

▓▓▓▓▓▓ attr()方法的实现

    用了和css()不同的方法

 1 // attr()方法 2 lquery.prototype.attr = function(attr,value){ 3  4     if(arguments.length == 2){  //设置 5         for(var i=0;i<this.elements.length;i++){ 6             this.elements[i].setAttribute(attr,value); 7         } 8     } 9     else if(arguments.length == 1){ //获取10         return this.elements[0].getAttribute(attr);11     }12     return this;13 };

 

▓▓▓▓▓▓ eq()方法的实现

    实现$('div').eq(1)

    由于eq()方法返回的对象要操作许多lQuery的方法,所以返回的对象必须是lQuery对象

1         lQuery.prototype.eq = function(num){2             return lQ(this.elements[num]);3         };

 

▓▓▓▓▓▓ index()方法的实现

    实现$('div').index() 返回这个元素在同辈元素中的位置

 1         lQuery.prototype.index = function(){ 2          3         var elems = this.elements[0].parentNode.children; 4          5         for(var i=0;i<elems.length;i++){ 6             if( elems[i] == this.elements[0] ){ 7                 return i; 8             } 9         }10     };    

 

▓▓▓▓▓▓ 阻止默认事件和阻止事件冒泡

    在jQuery中 return false 是阻止默认事件和事件冒泡,所以我们要对lQbind函数进行修改,通过判断绑定的函数的返回值是否为false来判断是否要进行阻止默认事件和阻止事件冒泡

 1     function lQbind(obj,events,fn){ 2             if(obj.addEventListener){ 3                 obj.addEventListener(events,function(ev){ 4                      5                     if( fn() == false ){ 6                         ev.preventDefault(); 7                         ev.cancelBubble = true; 8                     } 9                     10                 },false);11             }12             else{13                 obj.attachEvent('on'+events,function(){14                     15                     if( fn() == false ){16                         window.event.cancelBubble = true;17                         return false;18                     }19                     20                 });21             }22         }

 

▓▓▓▓▓▓ find()方法的实现

    仿写$('div').find('.box')和$('div').find('#box')方法

    这里涉及到通过判断find()参数第一个字符的方法来进行不同的操作和$()方法差不多,在循环时要使用concat()方法来连接数组,最后返回一个lQuery对象

 1         lQuery.prototype.find = function(sel){ 2              3             var arr = []; 4              5             if( sel.charAt(0) == '.' ){  6                 for(var i=0;i<this.elements.length;i++){     7                     arr = arr.concat(getClass( this.elements[i] , sel.substring(1) )); 8                 } 9             }10             else{  11                 for(var i=0;i<this.elements.length;i++){    12                     arr = arr.concat(toArray(this.elements[i].getElementsByTagName(sel)));13                 }14             }15             return lQ(arr);    16         };

 

    

第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台