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

2022-01-13,,,,

本篇文章主要对用原生JavaScript实现jQuery的某些简单功能进行详细全面的讲解,具有很好的参考价值,需要的朋友一起来看下吧

大致介绍

学习了妙味,用原生的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的某些简单功能的详细内容,更多请关注本站其它相关文章!

《详解用原生JavaScript实现jQuery的某些简单功能.doc》

下载本文的Word格式文档,以方便收藏与打印。