详解用原生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); };
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
上一篇: JS基于面向对象实现的选项卡效果示例
下一篇: JS高级运动实例分析
推荐阅读
-
详解用原生JavaScript实现jQuery的某些简单功能
-
用原生JavaScript实现jQuery的$.getJSON的解决方法
-
JavaScript实现的原生态兼容IE6可调可控滚动文字功能详解
-
用原生JS实现简单的多选框功能
-
原生JavaScript实现的简单省市县三级联动功能示例
-
原生JavaScript实现的无缝滚动功能详解
-
详解用原生JavaScript实现jQuery的某些简单功能
-
详解用Javascript实现的StopWatch功能实例教程
-
用原生JavaScript实现jQuery的$.getJSON的解决方法
-
用javascript实现jquery的document.ready功能的实现代码_javascript技巧