詳解用原生JavaScript實現(xiàn)jQuery的某些簡單功能
大致介紹
學習了妙味,用原生的JavaScript實現(xiàn)jQuery中的某些部分功能
定義自己的函數(shù)庫lQuery
$()選擇器的實現(xiàn)
jQuery是面向對象的,所以自己編寫的也要是面向對象的,看看基本的結構
// 定義lQuery對象
function lQuery(lArg){
}
function lQ(lArg){
return new lQuery(lArg);
}
// css()方法
lQuery.prototype.css = function(){};
// html()方法
lQuery.prototype.html = function(){};
先來仿寫jQuery中的$(函數(shù))的方法
// 定義lQuery對象
function lQuery(lArg){
// 用typeof判斷參數(shù)的類型是 function 、
switch( typeof lArg){
case 'function':
// 如果采用這種寫法,給lQ綁定相同的函數(shù),但是只會執(zhí)行一次
// window.onload = lArg;
// break;
}
}
如果寫出這樣的函數(shù)就會出現(xiàn)問題
lQ(function(){
alert(1);
});
lQ(function(){
alert(2);
});
這樣就只會彈出'2',但是在jQuery中都會彈出,所以上面的方法不對,我們采用事件綁定的形式來解決這個問題
// 綁定事件函數(shù)
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綁定相同的函數(shù),但是只會執(zhí)行一次
// window.onload = lArg;
// break;
lQbind(window,'load',lArg);
break;
}
仿寫jQuery中的$('.div')、$('#div')、$('div')三種方法
這三種方法的區(qū)別是第一個字符的不同,所以我們可以根據(jù)第一個字符的不同來進行區(qū)別對待
先來仿寫$('.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返回的是一個類數(shù)組NodeList,為了防止以后出現(xiàn)麻煩,要把他轉為一個 // 數(shù)組 this.elements = toArray(document.getElementsByTagName(lArg)); break;
由于getElementsByTagName返回的是一個類數(shù)組NodeList,為了防止以后出現(xiàn)麻煩,要把他轉為一個數(shù)組,自定義了一個toArray方法
// 將一個類數(shù)組轉為真正的數(shù)組
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()的實現(xiàn)
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()方法的實現(xiàn)
利用前面實現(xiàn)的綁定函數(shù)可以很容易的實現(xiàn)
lQuery.prototype.on = function(eventName,fn){
for(var i=0;i<this.elements.length;i++){
lQbind(this.elements[i],eventName,fn);
}
}
click()和mouseover()方法的實現(xiàn)
利用on()方法可以容易的實現(xiàn)
// 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()方法的實現(xiàn)
// 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()方法的實現(xiàn)
// hover()方法
lQuery.prototype.hover = function(fnover,fnout){
this.on('mouseover',fnover);
this.on('mouseout',fnout);
return this;
}
css()方法的實現(xiàn)
實現(xiàn)$('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()方法的實現(xiàn)
用了和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()方法的實現(xiàn)
實現(xiàn)$('div').eq(1)
由于eq()方法返回的對象要操作許多l(xiāng)Query的方法,所以返回的對象必須是lQuery對象
lQuery.prototype.eq = function(num){
return lQ(this.elements[num]);
};
index()方法的實現(xiàn)
實現(xiàn)$('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函數(shù)進行修改,通過判斷綁定的函數(shù)的返回值是否為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()方法的實現(xiàn)
仿寫$('div').find('.box')和$('div').find('#box')方法
這里涉及到通過判斷find()參數(shù)第一個字符的方法來進行不同的操作和$()方法差不多,在循環(huán)時要使用concat()方法來連接數(shù)組,最后返回一個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);
};
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
- jQuery實現(xiàn)隔行變色的方法分析(對比原生JS)
- 原生js仿jquery實現(xiàn)對Ajax的封裝
- 原生JS取代一些JQuery方法的簡單實現(xiàn)
- 原生js仿jquery一些常用方法(必看篇)
- 原生js封裝的一些jquery方法(詳解)
- 原生js實現(xiàn)jquery函數(shù)animate()動畫效果的簡單實例
- 原生js仿jquery animate動畫效果
- 原生js和jquery分別實現(xiàn)橫向導航菜單效果
- 原生JS和jQuery版實現(xiàn)文件上傳功能
- 使用jQuery或者原生js實現(xiàn)鼠標滾動加載頁面新數(shù)據(jù)
- 原生js和jQuery實現(xiàn)淡入淡出輪播效果
- 原生js與jQuery實現(xiàn)簡單的tab切換特效對比
相關文章
如何使用big.js解決JavaScript浮點數(shù)精度丟失問題
最近在項目中涉及到金額從元轉為分(乘100即可),發(fā)現(xiàn)乘法居然也會有精度丟失的問題,關于浮點數(shù)計算精度丟失是很多語言都存在的問題,本文給大家分享使用big.js解決JavaScript浮點數(shù)精度丟失問題,感興趣的朋友一起看看吧2023-12-12
跟我學習javascript的var預解析與函數(shù)聲明提升
跟我學習javascript的var預解析與函數(shù)聲明提升,小編對var預解析與函數(shù)聲明提升知識點也不甚了解,和大家一起學習本篇文章。2015-11-11
JavaScript文件的同步和異步加載的實現(xiàn)代碼
本篇文章主要介紹了JavaScript文件的同步和異步加載的實現(xiàn)代碼,具有一定的參考價值,有興趣的可以了解一下2017-08-08
js的window.showModalDialog及window.open用法實例分析
這篇文章主要介紹了js的window.showModalDialog及window.open用法,實例分析了window.showModalDialog與window.open方法的定義、功能與使用技巧,需要的朋友可以參考下2015-01-01

