DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> 詳解用原生JavaScript實現jQuery的某些簡單功能
詳解用原生JavaScript實現jQuery的某些簡單功能
編輯:關於JavaScript     

大致介紹

學習了妙味,用原生的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); 
 };

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持!

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved