簡易版jQuery——mQuery

前面的話

  雖然jQuery已經日漸式微,但它里面的許多思想,如選擇器、鏈式調用、方法函數化、取賦值合體等,有的已經變成了標準,有的一直影響到現在。所以,jQuery是一個偉大的前端框架。前端世界日新月異,由于實在是沒有時間去精讀源碼,于是自己封裝一個簡易版本的jQuery,來梳理jQuery的核心思路

?

基本構架

  由于火柴的英文是match,應該將這個簡單框架稱為mQuery。使用面向對象的寫法來寫mQuery,構造函數是Mquery(),調用$()方法,將根據Mquery()構造函數,創建一個實例對象

//構造函數
function Mquery(arg){}
function $(arg){return new Mquery(arg);
} 

  jquery幾大特征:

  1、通過$()選擇的元素都是一個集合,即使僅僅是一個元素

  因此,創建一個elements屬性為一個數組,去接收獲取的元素

//構造函數
function Mquery(arg){//保存所選擇的元素this.elements = [];
}

  2、鏈式調用

  所以,原型函數要返回this,以實現鏈式調用的效果

?

$函數

  $函數根據參數類型的不同,用途也不同

  1、參數為函數時,則直接運行

$(function(){console.log(1)
})

  2、參數為對象時,則把DOM對象轉換為$對象

$(document.body)

  3、參數為字符串時,則根據字符串選擇出元素,并轉換為$對象

$('#box')

  下面根據以上三個分類,來編寫Mquery構建函數

//事件綁定兼容寫法
function _addEvent(target,type,handler){if(target.addEventListener){target.addEventListener(type,function(e){//如果事件函數中出現 return false;則阻止默認事件和阻止冒泡if(typeof handler == 'function' && handler() === false){e.preventDefault();e.cancelBubble = true;}},false);}else{target.attachEvent('on'+type,function(event){if(typeof handler == 'function' && handler() === false){event.cancelBubble = true;event.returnValue = false;}return handler.call(target,event);});}
}//將類數組轉換成數組
function _toArray(arrayLike){return Array.prototype.slice.call(arrayLike);
}
//構造函數
function Mquery(arg){//保存所選擇的元素this.elements = [];switch(typeof arg){//當參數是函數時,如$(function(){})(),直接運行里面的代碼case 'function':_addEvent(window,'load',arg);break;//當參數是字符串時,選擇元素case 'string':this.elements = _toArray(document.querySelectorAll(arg));              break;//當參數是DOM對象時,將DOM對象轉換為$對象  case 'object':if(arg.constructor == Array){this.elements = arg;}else{this.elements.push(arg);}      break;}
}

?

HTML、CSS及特性設置

  下面來介紹常用的HTML、CSS及特性設置

【HTML】

  對于文本內容來說,一般地,有三種方法:html()、text()和val()。本文只實現最常用的html()方法

  當html()方法沒有參數時,表示獲取內容;有一個參數時,表示設置內容

//HTML獲取與設置
Mquery.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;
}

【CSS】

  對于CSS來說,有兩種參數格式:一種是json格式,一種是字符串格式

  當第一個參數為對象時,則判斷為json格式,否則為字符串格式

  對于字符串格式來說,只有一個參數時,為獲取樣式,兩個參數時,為設置樣式

  獲取樣式時,僅獲取當前集合中第0個元素的樣式;設置樣式時,則設置當前集合中所有元素的樣式

//獲取計算樣式兼容寫法
function _getCSS(obj,style){if(window.getComputedStyle){return getComputedStyle(obj)[style];}return obj.currentStyle[style];
}
//CSS獲取與設置
Mquery.prototype.css = function(attr,value){//如果是對象的形式,以對象的形式設置if(typeof attr == 'object'){for(var att in attr){for(var j = 0; j < this.elements.length; j++){this.elements[j].style[att] = attr[att];}}//如果不是對象的形式}else{//設置if(arguments.length == 2){for(var i = 0; i < this.elements.length; i++){this.elements[i].style[attr] = value;}//獲取}else if(arguments.length == 1){return _getCSS(this.elements[0],attr)}}return this;
}

【attr】

  特性設置與獲取的思路與CSS類似,只是方法變成了setAttribute()和getAttribute()

//attr獲取與設置
Mquery.prototype.attr = function(attr,value){//如果是對象的形式if(typeof attr == 'object'){for(var att in attr){for(var j = 0; j < this.elements.length; j++){this.elements[j].setAttribute(att,attr[att]);}}//如果不是對象的形式}else{//設置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;
}

?

事件綁定

【on】

  在jQuery中,最常用的事件綁定方法就是on方法。在on方法中要特別注意的是this的綁定,由于函數fn中的this實際上是window,所以應該將fn的this綁定到當前元素

//事件綁定
Mquery.prototype.on = function(eventType,fn){for(var i = 0; i < this.elements.length; i++){_addEvent(this.elements[i],eventType,fn.bind(this.elements[i));}return this;
}

【click和hover】

  click方法是一個簡寫方法

Mquery.prototype.click = function(fn){this.on('click',fn);return this;
}

  hover方法是mouseover和mouseout的合成方法

Mquery.prototype.hover = function(fnOver,fnOut){this.on('mouseover',fnOver);this.on('mouseout',fnOut);return this;
}

【return false】

  在jQuery中,使用return false可以同時阻止默認行為和阻止冒泡

//事件綁定兼容寫法
function _addEvent(target,type,handler){if(target.addEventListener){target.addEventListener(type,function(e){//如果事件函數中出現 return false;則阻止默認事件和阻止冒泡if(typeof handler == 'function' && handler() === false){e.preventDefault();e.cancelBubble = true;}},false);}else{target.attachEvent('on'+type,function(event){if(typeof handler == 'function' && handler() === false){event.cancelBubble = true;event.returnValue = false;}return handler.call(target,event);});}
}

?

其他設置

  jQuery的功能非常強大。下面選擇一些常用功能進行實現

【顯示隱藏】

//隱藏
Mquery.prototype.hide = function(){for(var i = 0; i < this.elements.length; i++){//保存當前元素的display值this.elements[i].displayValue = this.elements[i].style.display;this.elements[i].style.display = 'none';}return this;
}
//顯示
Mquery.prototype.show = function(){for(var i = 0; i < this.elements.length; i++){this.elements[i].style.display = this.elements[i].displayValue;//刪除保存的元素的display值delete this.elements[i].displayValue;}return this;
}

【插件設置】

$.extend = function(json){ for(var attr in json){$[attr] = json[attr];}
};
$.fn = {};
$.fn.extend = function(json){for(var attr in json){Mquery.prototype[attr] = json[attr];} 
};

【索引設置】

//根據索引選擇元素
Mquery.prototype.eq = function(number){return $(this.elements[number]);
}//根據元素獲取索引
Mquery.prototype.index = function(){var elements = this.elements[0].parentNode.children;for(var i = 0; i < elements.length; i++){if(elements[i] === this.elements[0]){return i;}}
}

【子級篩選】

//篩選出當前匹配的元素集合中每個元素的后代
Mquery.prototype.find = function(str){var arr = [];for(var i = 0; i < this.elements.length; i++){Array.prototype.push.apply(arr,this.elements[i].querySelectorAll(str));}return $(arr);
}

?

完整源碼

  下面是mQuery的完整源碼

//事件綁定兼容寫法
function _addEvent(target,type,handler){if(target.addEventListener){target.addEventListener(type,function(e){//如果事件函數中出現 return false;則阻止默認事件和阻止冒泡if(typeof handler == 'function' && handler() === false){e.preventDefault();e.cancelBubble = true;}},false);}else{target.attachEvent('on'+type,function(event){if(typeof handler == 'function' && handler() === false){event.cancelBubble = true;event.returnValue = false;}return handler.call(target,event);});}
}
//獲取計算樣式兼容寫法
function _getCSS(obj,style){if(window.getComputedStyle){return getComputedStyle(obj)[style];}return obj.currentStyle[style];
}//將類數組轉換成數組
function _toArray(arrayLike){return Array.prototype.slice.call(arrayLike);
}
//構造函數
function Mquery(arg){//保存所選擇的元素this.elements = [];switch(typeof arg){//當參數是函數時,如$(function(){})(),直接運行里面的代碼case 'function':_addEvent(window,'load',arg);break;//當參數是字符串時,選擇元素case 'string':this.elements = _toArray(document.querySelectorAll(arg));              break;//當參數是DOM對象時,將DOM對象轉換為$對象  case 'object':if(arg.constructor == Array){this.elements = arg;}else{this.elements.push(arg);}      break;}
}
//根據索引選擇元素
Mquery.prototype.eq = function(number){return $(this.elements[number]);
}
//根據元素獲取索引
Mquery.prototype.index = function(){var elements = this.elements[0].parentNode.children;for(var i = 0; i < elements.length; i++){if(elements[i] === this.elements[0]){return i;}}
}
//篩選出當前匹配的元素集合中每個元素的后代
Mquery.prototype.find = function(str){var arr = [];for(var i = 0; i < this.elements.length; i++){Array.prototype.push.apply(arr,this.elements[i].querySelectorAll(str));}return $(arr);
}
//CSS獲取與設置
Mquery.prototype.css = function(attr,value){//如果是對象的形式,以對象的形式設置if(typeof attr == 'object'){for(var att in attr){for(var j = 0; j < this.elements.length; j++){this.elements[j].style[att] = attr[att];}}//如果不是對象的形式}else{//設置if(arguments.length == 2){for(var i = 0; i < this.elements.length; i++){this.elements[i].style[attr] = value;}//獲取}else if(arguments.length == 1){return _getCSS(this.elements[0],attr)}}return this;
}
//attr獲取與設置
Mquery.prototype.attr = function(attr,value){//如果是對象的形式if(typeof attr == 'object'){for(var att in attr){for(var j = 0; j < this.elements.length; j++){this.elements[j].setAttribute(att,attr[att]);}}//如果不是對象的形式}else{//設置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;
}
//HTML獲取與設置
Mquery.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;
}
//隱藏
Mquery.prototype.hide = function(){for(var i = 0; i < this.elements.length; i++){//保存當前元素的display值this.elements[i].displayValue = this.elements[i].style.display;this.elements[i].style.display = 'none';}return this;
}
//顯示
Mquery.prototype.show = function(){for(var i = 0; i < this.elements.length; i++){this.elements[i].style.display = this.elements[i].displayValue;//刪除保存的元素的display值delete this.elements[i].displayValue;}return this;
}
//事件綁定
Mquery.prototype.on = function(eventType,fn){for(var i = 0; i < this.elements.length; i++){_addEvent(this.elements[i],eventType,fn.bind(this.elements[i]));}return this;
}
//click簡寫
Mquery.prototype.click = function(fn){this.on('click',fn);return this;
}
//鼠標移入移出
Mquery.prototype.hover = function(fnOver,fnOut){this.on('mouseover',fnOver);this.on('mouseout',fnOut);return this;
}
$.extend = function(json){ for(var attr in json){$[attr] = json[attr];}
};
$.fn = {};
$.fn.extend = function(json){for(var attr in json){Mquery.prototype[attr] = json[attr];} 
};
function $(arg){return new Mquery(arg);
} 

?

實際應用

  下面使用mQuery來實現一個簡單的效果

<style>
div { width:60px; height:60px; margin:5px; float:left; }
</style>
<span id="result"></span>
<div style="background-color:blue;"></div>
<div style="background-color:rgb(15,99,30);"></div>
<div style="background-color:#123456;"></div>
<div style="background-color:#f11;"></div>
<script src="mQuery.js"></script>
<script>
$("div").click(function(){$("#result").html("背景顏色是 " + $(this).css("background-color"));
})
</script> 

  點擊不同顏色的元素塊,將在右側顯示具體的顏色值

  

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/257446.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/257446.shtml
英文地址,請注明出處:http://en.pswp.cn/news/257446.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LaTeX?安裝配置?OSX

LaTeX 安裝配置 OSX官方網站&#xff1a;http://www.latex-project.orghttp://www.tug.org/mactex/http://pages.uoregon.edu/koch/BasicTeX.pdf完整的Tex超過2G&#xff0c;一般用戶沒必要&#xff0c;可以先安裝BasicTeX&#xff0c;當有需要時include必要的庫即可1.安裝Basi…

php 正三角塔,PHP 環境塔建與數據類型轉換

手動塔建PHP開發環境安裝php c:\apps\php安裝apache c:\apps\apache1.配制apache配制c:\apps\apache\conf\httpd.confDocumentRoot"c:/apps/www" //指定工作目錄,WWW為自已創健Directoryindex index.php index.html // 加入:loadModule php5_module "c:\apps\PH…

C/C++基礎知識:函數指針和指針函數的基本概念

【函數指針】 在程序運行中&#xff0c;函數代碼是程序的算法指令部分&#xff0c;它們和數組一樣也占用存儲空間&#xff0c;都有相應的地址。可以使用指針變量指向數組的首地址&#xff0c;也可以使用指針變量指向函數代碼的首地址&#xff0c;指向函數代碼首地址的指針…

告警系統郵件引擎

2019獨角獸企業重金招聘Python工程師標準>>> 20.23-20.25 告警系統郵件引擎 創建發郵件的腳本——mail.py [rootlocalhost mail]# pwd /usr/local/sbin/mon/mail[rootlocalhost mail]# vim mail.py #!/usr/bin/env python #-*- coding: UTF-8 -*- import os,sys rel…

【HTTP 2】簡介(Introduction)

前情提要 在上一篇文章《【HTTP 2.0】 序言》中&#xff0c;我們簡要介紹了 HTTP 2 協議的概要和協議狀態。 在本篇文章中&#xff0c;我們將會了解到 HTTP 2 協議簡介&#xff08;Introduction&#xff09;部分的內容。 簡介&#xff08;Introduction&#xff09; 超文本傳輸協…

java測試類生成對象,java編寫student類 用Java編寫一段測試程序,生成student類的兩個對象,并輸出每個對象基本信息?...

java中怎么創建對象數組&#xff1f;比如我創建了一個學生類Student&#xff0c;怎么用這個類創建一個對象數組&#xff0c;麻煩給個例子&#xff1f;學生類&#xff1a;classA{privateStringnameprivateintagepublicStringgetName(){returnname}publicvoidsetName(Stringname)…

iOS -- SKScene類

SKScene類 繼承自SKEffectNode:SKNode:UIResponder:NSObject符合NSCoding(SKNode)NSCopying(SKNode)NSObject(NSObject)框架 /System/Library/Frameworks/SpriteKit.framework可用性可用于iOS 7.0或者更晚的版本聲明于SKScene.h參考指南Sprite Kit Progamming Guide概覽 重要提…

SSD硬盤 全盤安全擦除

此文From http://ssd.zol.com.cn/575/5753057.html 在SSD固態硬盤的使用過程中&#xff0c;部分用戶可能會碰到計算機意外掉電或死機并強行斷電后&#xff0c;系統出現異常&#xff0c;掃描SSD后發現壞塊&#xff0c;然后一著急一跺腳甚至想返廠維修。 其實掉電后固態硬盤出現壞…

php中等3秒再跳轉,跳轉和重定向

頁面跳轉在應用開發中&#xff0c;經常會遇到一些帶有提示信息的跳轉頁面&#xff0c;例如操作成功或者操作錯誤頁面&#xff0c;并且自動跳轉到另外一個目標頁面。系統的ThinkController類內置了兩個跳轉方法success和error&#xff0c;用于頁面跳轉提示&#xff0c;而且可以支…

2017敏捷沙灘大會:完美軟件,測量持續交付,以及探索未來

在英國康沃爾郡舉行的2017敏捷沙灘大會上&#xff0c;數百名演講者和參與者共聚一堂&#xff0c;探討敏捷和后敏捷領域軟件開發方法有哪些最新進展。本次大會最后一個下午的要點包括&#xff1a;交付團隊可以通過擁抱精益、迭代和持續的部署方法更快速地實現業務價值&#xff1…

做fzu oj 1045 做減法學到的sprintf()函數

題目 做題一直輸不出答案&#xff0c;于是就上網去百度了這題的解題&#xff0c;發現解答十分的簡短&#xff0c;而且其中我看見了平時沒見過的函數&#xff0c;sprintf()。 于是就百度sprintf()的使用。 如下&#xff1a; 函數功能&#xff1a;把格式化的數據寫入某個字符串 函…

動態內存分配及變量存儲類別(第二部分)

5. C語言變量的存儲類別和生存期 我們知道&#xff0c;變量是有數據類型的&#xff0c;用以說明它占用多大的內存空間&#xff0c;可以進行什么樣的操作。除了數據類型&#xff0c;變量還有一個屬性&#xff0c;稱為“存儲類別”。存儲類別就是數據在內存中的存放區域。一個正在…

oracle的em能干什么,轉載?解決Oracle的EM登錄

轉載 解決Oracle的EM登錄(2011-03-13 20:53:39)標簽&#xff1a;雜談這幾天解決了EM無法登錄的問題&#xff0c;順便也把j數據庫程序中常出現的ORA_12518錯誤解決了&#xff0c;有必要總結一下&#xff0c;我最初遇到的情況是這樣的&#xff1a;1. 編寫java程序訪問oracle數據庫…

python 回溯法 子集樹模板 系列 —— 1、8 皇后問題

問題 88格的國際象棋上擺放八個皇后&#xff0c;使其不能互相攻擊&#xff0c;即任意兩個皇后都不能處于同一行、同一列或同一斜線上&#xff0c;問有多少種擺法。 分析 為了簡化問題&#xff0c;考慮到8個皇后不同行&#xff0c;則每一行放置一個皇后&#xff0c;每一行的皇后…

Core Java Volume I — 3.6. Strings

3.6. StringsConceptually, Java strings are sequences of Unicode characters&#xff08;Java的字符串是一個Unicode序列&#xff09;. For example, the string "Java\u2122" consists of the five Unicode characters J, a, v, a, and ?. Java does not have a…

Android實用代碼七段(五)

前言 每次分享意味著每次都有進步&#xff0c;本系列以實用為主&#xff0c;歡迎和我分享和推薦好用的代碼段~~聲明歡迎轉載&#xff0c;但請保留文章原始出處:) 博客園&#xff1a;http://www.cnblogs.com農民伯伯&#xff1a; http://over140.cnblogs.com 正文 1、展開、收起…

oracle 自增1,oracle自增無法從1開始

問題描述我想讓XH字段從1開始增加,由于是varchar類型的,所以就用這種方式,但我發現我的數據表中XH字段是從217開始增加的,為什么啊問題出現的環境背景及自己嘗試過哪些方法相關代碼// 請把代碼文本粘貼到下方(請勿用圖片代替代碼)declarej number;i number;begini:1;j:1;for i …

ceph Luminous版手動安裝零散記錄

1.安裝必要的依賴包&#xff0c;關防火墻&#xff0c;向/etc/hosts內添加域名等 2.安裝ceph 配置yum源 (如果嫌慢&#xff0c;可以配置cachedir/home/yum/$basearch/$releasever和keepcache1兩個參數&#xff0c;在第一次安裝時將安裝包下載到本地做成yum源&#xff0c;給后面的…

C#最簡單最完整的webservice實例

我做java&#xff0c;但最近接觸crm所以必須研究一下C#中的webservice以備后用&#xff0c;其實就是個新手&#xff0c;哈哈&#xff0c;這個實例是我在參考了網上諸多不完整的例子的情況下&#xff0c;自己摸索完成的。期間遇到過一系列的棘手的問題&#xff0c;經過個人努力終…

2015 UESTC 數據結構專題G題 秋實大哥去打工 單調棧

秋實大哥去打工 Time Limit: 1 Sec Memory Limit: 256 MB 題目連接 http://acm.uestc.edu.cn/#/contest/show/59Description 天行健&#xff0c;君子以自強不息。地勢坤&#xff0c;君子以厚德載物。天天過節的秋實大哥又要過節了&#xff0c;于是他要給心愛的妹子買禮物。但由…