仿照jquery封装一个自己的js库

所谓造轮子的好处就是复习知识点,加深对原版jquery的理解。
本文系笔者学习jquery的笔记,记述一个名为"dQuery"的初级版和缩水版jquery库的实现。主要涉及知识点包括面向对象,jquery,绑定,脚本化css等。


一. jquery的美元符意味什么?

先思考alert(typeof $)的结果中的$,它是一个对象,也是一个函数。
所以美元符字面上是jQuery,其实就是一个jq对象,里面可以接受函数,字符串(#xxx,.xxx,xxx...),还有一种是对象(比如this)。

dQuery是基于面向对象实现的,所以需要先写构造函数。为了方便遍历和其它方法操作,所有内容返回到一个数组中。这个数组依附于dQuery对象存在,之后将为这个dquery对象属性添加方法。

function dQuery(vArg){//参数是变体变量 this.elements=[];//选择器选择的元素扔到这个数组中 }

因为新的对象可以接受三种类型的参数(字符串,对象,函数)。作为一个变体变量,根据匈牙利命名法可以用vXxx命名,同时需要分类讨论变量的情况:

1.当参数为函数时,执行函数——window.onload.——不好。

jquery写作时,经常允许多个$(function()),但是写window.onload会导致最终只执行最后一个。这时需要给函数绑定window.onload事件。
绑定事件的函数如下:

function myAddEvent(obj,sEv,fn){ if(obj.attachEvent){ obj.attachEvent('on'+sEv,fn); }else{ obj.addEventListener(sEv,fn,false); } }

所以,当为id选择器时,查找:document.getElementById(vArg.substring(1));并把它加到this.elements中去。

2.当参数为字符串时,执行选择器操作.

这里需要对id选择器,类选择器,元素选择器进行判断。
注意:把选择器结果丢到一个数组(dQuery.elements)中去。方便遍历事件。
用charAt进行判断参数首位:(#,.或是其它)

(1)首位为#时:

执行document.getElementById,同时把这个字符串稍作处理,用substring(1)方法把首个字符给去掉。

(2)首位为.

选取class类。可以设计一个getByClass函数

function getByClass(oParent,sClass){ var aEle=oParent.getElementsByTagName('*');//选择父元素的所有元素 var aResult=[]; var re=new RegExp('\\b'+sClass+'\\b','i');//正则边界 var i=0; for(i=0;i<aEle.length;i++){ if(re.test(aEle[i].className)){ aResult.push(aEle[i]); } } return aResult; }

在本实例中,oParent父级对象实际上就是document,另一方面,因为getByClass返回的对象实际是一个数组,所以:

this.elements=getByClass(document,vArg.substring(1));
(3)参数为对象时,返回一个对象本身

把这个对象push到

(4)绑定基本的事件——比如点击事件

在接下来就是绑定事件。比如click(function(){}),它是一个回调函数。需要用到原型(prototype)方法。

//对选择器函数绑定click事件
dQuery.prototype.click=function(fn){ var i=0; //对于返回器数组的内容 for(i=0;i<this.elements.length;i++){ myAddEvent(this.elements[i],'click',fn); } }
(5)简写设置

到目前为止,在调用这个dQuery时,每次都需要这样写:

new dQuery(function(){ new dQuery('input').click(function(){ alert('a'); }) });

每次都要使用new,不用就会出问题。
如果我想使用类似jquery的简写方式,使用$d作为简写,可以通过一个函数来定义:

function $d(vArg){ return new dQuery(vArg); }

所以当前的最终代码为:

//可重复调用的加载函数
function myAddEvent(obj,sEv,fn){ if(obj.attachEvent){ obj.attachEvent('on'+sEv,fn); }else{ obj.addEventListener(sEv,fn,false); } } //class选择器调用函数 function getByClass(oParent,sClass){ var aEle=oParent.getElementsByTagName('*');//选择父元素的所有元素 var aResult=[]; var re=new RegExp('\\b'+sClass+'\\b','i');//正则边界 var i=0; for(i=0;i<aEle.length;i++){ if(re.test(aEle[i].className)){ aResult.push(aEle[i]); } } return aResult; } //定义dQuery对象 function dQuery(vArg){//参数是变体变量 this.elements=[];//选择器选择的元素扔到这个数组中 switch(typeof vArg){ //如果参数是函数 case 'function': myAddEvent(window,'load',vArg); break; //如果参数是字符串 case 'string': switch(vArg.charAt(0)){ case '#'://id选择器参数应该为#号之后的字符段 var obj=document.getElementById(vArg.substring(1)); this.elements.push(obj); break; case '.'://class this.elements=getByClass(document,vArg.substring(1)); break; default://标签 this.elements=document.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值