简易版jQuery——mQuery
前面的話
雖然jQuery已經(jīng)日漸式微,但它里面的許多思想,如選擇器、鏈?zhǔn)秸{(diào)用、方法函數(shù)化、取賦值合體等,有的已經(jīng)變成了標(biāo)準(zhǔn),有的一直影響到現(xiàn)在。所以,jQuery是一個(gè)偉大的前端框架。前端世界日新月異,由于實(shí)在是沒有時(shí)間去精讀源碼,于是自己封裝一個(gè)簡易版本的jQuery,來梳理jQuery的核心思路
?
基本構(gòu)架
由于火柴的英文是match,應(yīng)該將這個(gè)簡單框架稱為mQuery。使用面向?qū)ο蟮膶懛▉韺憁Query,構(gòu)造函數(shù)是Mquery(),調(diào)用$()方法,將根據(jù)Mquery()構(gòu)造函數(shù),創(chuàng)建一個(gè)實(shí)例對象
//構(gòu)造函數(shù) function Mquery(arg){} function $(arg){return new Mquery(arg); }jquery幾大特征:
1、通過$()選擇的元素都是一個(gè)集合,即使僅僅是一個(gè)元素
因此,創(chuàng)建一個(gè)elements屬性為一個(gè)數(shù)組,去接收獲取的元素
//構(gòu)造函數(shù) function Mquery(arg){//保存所選擇的元素this.elements = []; }2、鏈?zhǔn)秸{(diào)用
所以,原型函數(shù)要返回this,以實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用的效果
?
$函數(shù)
$函數(shù)根據(jù)參數(shù)類型的不同,用途也不同
1、參數(shù)為函數(shù)時(shí),則直接運(yùn)行
$(function(){console.log(1) })2、參數(shù)為對象時(shí),則把DOM對象轉(zhuǎn)換為$對象
$(document.body)3、參數(shù)為字符串時(shí),則根據(jù)字符串選擇出元素,并轉(zhuǎn)換為$對象
$('#box')下面根據(jù)以上三個(gè)分類,來編寫Mquery構(gòu)建函數(shù)
//事件綁定兼容寫法 function _addEvent(target,type,handler){if(target.addEventListener){target.addEventListener(type,function(e){//如果事件函數(shù)中出現(xiàn) return false;則阻止默認(rèn)事件和阻止冒泡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);});} }//將類數(shù)組轉(zhuǎn)換成數(shù)組 function _toArray(arrayLike){return Array.prototype.slice.call(arrayLike); } //構(gòu)造函數(shù) function Mquery(arg){//保存所選擇的元素this.elements = [];switch(typeof arg){//當(dāng)參數(shù)是函數(shù)時(shí),如$(function(){})(),直接運(yùn)行里面的代碼case 'function':_addEvent(window,'load',arg);break;//當(dāng)參數(shù)是字符串時(shí),選擇元素case 'string':this.elements = _toArray(document.querySelectorAll(arg)); break;//當(dāng)參數(shù)是DOM對象時(shí),將DOM對象轉(zhuǎn)換為$對象 case 'object':if(arg.constructor == Array){this.elements = arg;}else{this.elements.push(arg);} break;} }?
HTML、CSS及特性設(shè)置
下面來介紹常用的HTML、CSS及特性設(shè)置
【HTML】
對于文本內(nèi)容來說,一般地,有三種方法:html()、text()和val()。本文只實(shí)現(xiàn)最常用的html()方法
當(dāng)html()方法沒有參數(shù)時(shí),表示獲取內(nèi)容;有一個(gè)參數(shù)時(shí),表示設(shè)置內(nèi)容
//HTML獲取與設(shè)置 Mquery.prototype.html = function(str){//設(shè)置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來說,有兩種參數(shù)格式:一種是json格式,一種是字符串格式
當(dāng)?shù)谝粋€(gè)參數(shù)為對象時(shí),則判斷為json格式,否則為字符串格式
對于字符串格式來說,只有一個(gè)參數(shù)時(shí),為獲取樣式,兩個(gè)參數(shù)時(shí),為設(shè)置樣式
獲取樣式時(shí),僅獲取當(dāng)前集合中第0個(gè)元素的樣式;設(shè)置樣式時(shí),則設(shè)置當(dāng)前集合中所有元素的樣式
//獲取計(jì)算樣式兼容寫法 function _getCSS(obj,style){if(window.getComputedStyle){return getComputedStyle(obj)[style];}return obj.currentStyle[style]; } //CSS獲取與設(shè)置 Mquery.prototype.css = function(attr,value){//如果是對象的形式,以對象的形式設(shè)置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{//設(shè)置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】
特性設(shè)置與獲取的思路與CSS類似,只是方法變成了setAttribute()和getAttribute()
//attr獲取與設(shè)置 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{//設(shè)置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的綁定,由于函數(shù)fn中的this實(shí)際上是window,所以應(yīng)該將fn的this綁定到當(dāng)前元素
//事件綁定 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方法是一個(gè)簡寫方法
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可以同時(shí)阻止默認(rèn)行為和阻止冒泡
//事件綁定兼容寫法 function _addEvent(target,type,handler){if(target.addEventListener){target.addEventListener(type,function(e){//如果事件函數(shù)中出現(xiàn) return false;則阻止默認(rèn)事件和阻止冒泡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);});} }?
其他設(shè)置
jQuery的功能非常強(qiáng)大。下面選擇一些常用功能進(jìn)行實(shí)現(xiàn)
【顯示隱藏】
//隱藏 Mquery.prototype.hide = function(){for(var i = 0; i < this.elements.length; i++){//保存當(dāng)前元素的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; }【插件設(shè)置】
$.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];} };【索引設(shè)置】
//根據(jù)索引選擇元素 Mquery.prototype.eq = function(number){return $(this.elements[number]); }//根據(jù)元素獲取索引 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;}} }【子級篩選】
//篩選出當(dāng)前匹配的元素集合中每個(gè)元素的后代 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){//如果事件函數(shù)中出現(xiàn) return false;則阻止默認(rèn)事件和阻止冒泡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);});} } //獲取計(jì)算樣式兼容寫法 function _getCSS(obj,style){if(window.getComputedStyle){return getComputedStyle(obj)[style];}return obj.currentStyle[style]; }//將類數(shù)組轉(zhuǎn)換成數(shù)組 function _toArray(arrayLike){return Array.prototype.slice.call(arrayLike); } //構(gòu)造函數(shù) function Mquery(arg){//保存所選擇的元素this.elements = [];switch(typeof arg){//當(dāng)參數(shù)是函數(shù)時(shí),如$(function(){})(),直接運(yùn)行里面的代碼case 'function':_addEvent(window,'load',arg);break;//當(dāng)參數(shù)是字符串時(shí),選擇元素case 'string':this.elements = _toArray(document.querySelectorAll(arg)); break;//當(dāng)參數(shù)是DOM對象時(shí),將DOM對象轉(zhuǎn)換為$對象 case 'object':if(arg.constructor == Array){this.elements = arg;}else{this.elements.push(arg);} break;} } //根據(jù)索引選擇元素 Mquery.prototype.eq = function(number){return $(this.elements[number]); } //根據(jù)元素獲取索引 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;}} } //篩選出當(dāng)前匹配的元素集合中每個(gè)元素的后代 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獲取與設(shè)置 Mquery.prototype.css = function(attr,value){//如果是對象的形式,以對象的形式設(shè)置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{//設(shè)置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獲取與設(shè)置 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{//設(shè)置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獲取與設(shè)置 Mquery.prototype.html = function(str){//設(shè)置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++){//保存當(dāng)前元素的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; } //鼠標(biāo)移入移出 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); }?
實(shí)際應(yīng)用
下面使用mQuery來實(shí)現(xiàn)一個(gè)簡單的效果
<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>點(diǎn)擊不同顏色的元素塊,將在右側(cè)顯示具體的顏色值
總結(jié)
以上是生活随笔為你收集整理的简易版jQuery——mQuery的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java项目开发——使用MAP和实体类作
- 下一篇: 【管理】日报,周报,会议记录模板