详解用原生JavaScript实现jQuery的某些简单功能,用原生JavaScript实现jQuery的某些简单功能

详解用原生JavaScript实现jQuery的某些简单功能,javascriptjquery

大致介绍

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

定义自己的函数库lQuery

$()选择器的实现

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

// 定义lQuery对象
function lQuery(lArg){
}
function lQ(lArg){
 return new lQuery(lArg);
}
// css()方法
lQuery.prototype.css = function(){};
// html()方法
lQuery.prototype.html = function(){};

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

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

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

lQ(function(){
  alert(1);
 });
 lQ(function(){
  alert(2);
 });

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

// 绑定事件函数
function lQbind(obj,eventName,fn){
 // 标准浏览器
 if(obj.addEventListener){
 obj.addEventListener(eventName,fn,false);
 }else{
 // IE浏览器
 obj.attachEvent('on'+eventName,fn);
 }
}

可以使用这样调用

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

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

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

先来仿写$(‘.div’)

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

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

 // 获取class属性
function getClass(obj,name){
 var arr = [];
 var elems = obj.getElementsByTagName('*');
 for(var i=0;i<elems.length;i++){
 if(elems[i].className == name){
  arr.push(elems[i]);
 }
 }
 return arr;
}

仿写$(‘#div’)

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

仿写$(‘div’)

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

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

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

仿写$(对象)的方法

      // window  document
      case ‘object’:
          this.elements.push(lArg);
          break;

html()的实现

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

// html()方法
lQuery.prototype.html = function(str){
 if(str){ //设置
 for(var i=0;i<this.elements.length;i++){
  this.elements[i].innerHTML = str;
 }
 }else{
 return this.elements[0].innerHTML;
 }
 return this;
};

on()方法的实现

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

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

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

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

// click()方法
lQuery.prototype.click = function(fn){
 this.on('click',fn);
 return this;
}
// mouseover()方法
lQuery.prototype.mouseover = function(fn){
 this.on('mouseover',fn);
 return this;
}

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

// hide()方法
lQuery.prototype.hide = function(){
 for(var i=0;i<this.elements.length;i++){
 this.elements[i].style.display = 'none';
 }
 return this;
}
// show()方法
lQuery.prototype.show = function(){
 for(var i=0;i<this.elements.length;i++){
 this.elements[i].style.display = 'block';
 }
 return this;
}

hover()方法的实现

 // hover()方法
 lQuery.prototype.hover = function(fnover,fnout){
 this.on('mouseover',fnover);
 this.on('mouseout',fnout);
 return this;
 }

css()方法的实现

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

lQuery.prototype.css = function(attr,value){
 if(arguments.length == 2){
 for(var i=0;i<this.elements.length;i++){
  this.elements[i].attr = value;
 }
 }
 if(arguments.length == 1){
 return getStyle(this.elements[0],attr);
 }
}

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

// 获取属性
function getStyle(obj,attr){
 if(obj.currentStyle[attr]){
 obj.currentStyle[attr];
 }else{
 obj.getComputedStyle(obj,false)[attr];
 }
}

attr()方法的实现

用了和css()不同的方法

// attr()方法
lquery.prototype.attr = function(attr,value){
 if(arguments.length == 2){ //设置
 for(var i=0;i<this.elements.length;i++){
  this.elements[i].setAttribute(attr,value);
 }
 }
 else if(arguments.length == 1){ //获取
 return this.elements[0].getAttribute(attr);
 }
 return this;
};

eq()方法的实现

 实现$(‘div’).eq(1)

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

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

index()方法的实现

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

lQuery.prototype.index = function(){
 var elems = this.elements[0].parentNode.children;
 for(var i=0;i<elems.length;i++){
  if( elems[i] == this.elements[0] ){
  return i;
  }
 }
 };

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

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

function lQbind(obj,events,fn){
  if(obj.addEventListener){
  obj.addEventListener(events,function(ev){ 
   if( fn() == false ){
   ev.preventDefault();
   ev.cancelBubble = true;
   }
  },false);
  }
  else{
  obj.attachEvent('on'+events,function(){
   if( fn() == false ){
   window.event.cancelBubble = true;
   return false;
   }
  });
  }
 }

find()方法的实现

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

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

lQuery.prototype.find = function(sel){
  var arr = [];
  if( sel.charAt(0) == '.' ){ 
  for(var i=0;i<this.elements.length;i++){ 
   arr = arr.concat(getClass( this.elements[i] , sel.substring(1) ));
  }
  }
  else{ 
  for(var i=0;i<this.elements.length;i++){ 
   arr = arr.concat(toArray(this.elements[i].getElementsByTagName(sel)));
  }
  }
  return lQ(arr); 
 };

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持帮客之家!

大致介绍 学习了妙味,用原生的JavaScript实现jQuery中的某些部分功能
定义自己的…

仿写$(‘#div’)

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

    在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         }

 

function lQbind(obj,events,fn){
  if(obj.addEventListener){
  obj.addEventListener(events,function(ev){ 
   if( fn() == false ){
   ev.preventDefault();
   ev.cancelBubble = true;
   }
  },false);
  }
  else{
  obj.attachEvent('on'+events,function(){
   if( fn() == false ){
   window.event.cancelBubble = true;
   return false;
   }
  });
  }
 }

▓▓▓▓▓▓ 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 }

 

// hide()方法
lQuery.prototype.hide = function(){
 for(var i=0;i<this.elements.length;i++){
 this.elements[i].style.display = 'none';
 }
 return this;
}
// show()方法
lQuery.prototype.show = function(){
 for(var i=0;i<this.elements.length;i++){
 this.elements[i].style.display = 'block';
 }
 return this;
}

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

    实现$(‘div’).eq(1)

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

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

 

hover()方法的实现

▓▓▓▓▓▓ 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 };

 

find()方法的实现

▓▓▓▓▓▓ 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         };

 

    

用原生JavaScript实现jQuery的某些简单功能,javascriptjquery ▓▓▓▓▓▓ 大致
介绍 学习了妙味,用原生的JavaScript实现jQ…

先来仿写$(‘.div’)

 

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

▓▓▓▓▓▓ 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 }

 

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

▓▓▓▓▓▓ 大致介绍

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

    定义自己的函数库lQuery

 

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

▓▓▓▓▓▓ 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 }

 

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

▓▓▓▓▓▓ 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 }

 

 

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

▓▓▓▓▓▓ 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 };

 

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

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

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

▓▓▓▓▓▓ 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     };    

 

lQuery.prototype.find = function(sel){
  var arr = [];
  if( sel.charAt(0) == '.' ){ 
  for(var i=0;i<this.elements.length;i++){ 
   arr = arr.concat(getClass( this.elements[i] , sel.substring(1) ));
  }
  }
  else{ 
  for(var i=0;i<this.elements.length;i++){ 
   arr = arr.concat(toArray(this.elements[i].getElementsByTagName(sel)));
  }
  }
  return lQ(arr); 
 };

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

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

 

$()选择器的实现

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

    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  document
2         case 'object':
3             this.elements.push(lArg);
4             break;

eq()方法的实现

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

css()方法的实现

定义自己的函数库lQuery

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

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

 // 获取class属性
function getClass(obj,name){
 var arr = [];
 var elems = obj.getElementsByTagName('*');
 for(var i=0;i<elems.length;i++){
 if(elems[i].className == name){
  arr.push(elems[i]);
 }
 }
 return arr;
}