簡易版jquery

最近寫了一個簡易版的jquery   github地址:https://github.com/jiangzhenfei/Easy-Jquerycss

完成的方法:html

1.$('#id')前端

2.extend擴展方法,在JQuery或者原型上擴展更多的方法,該方法也是擴展jq插件的方法jquery

3.pushStack方法,該方法是$('#id').find('div').end(),找到jq對象的關聯對象和返回上一個對象的基礎git

4.實現一些基本的工具方法,$.each,$.each,$.map,$.grep,$.mergegithub

5.實現獲取自定義屬性,獲取和設置樣式的方法json

6.實現簡易的Callback數組

7.實現簡易的Defferd延遲對象緩存

8.實現數據緩存Data前端框架


 

所有代碼:

/**
 * 設置當前激活的tab頁順序
 *
 * @param { selector } 指的是當前的選擇器
 * $(''#app li) 指的就是在id爲app的元素內部全部的li集合,返回是數組
 */
var $ = function(selector){
    return new $.prototype.init(selector)
}
$.prototype={
    length:0,
    constructor: $,
    init:function(selector){
        //不存在selector
        if(!selector){
            return this;
        }
        //是對象時候至關於觸發domLoad
        if(this.isFunction(selector)){
            this.ready(selector)
            return;
        }
        let doms = document.querySelectorAll( selector )
        let i = doms.length;
        while( i-- ){
            this[ i ] = doms[ i ]
        }
        return this;
    },
    /*判斷是否爲對象 (簡單對象)*/
    isObject:function (value){
        return Object.getPrototypeOf( value ) === Object.prototype
    },
    /*判斷是否爲數組 */
    isArray:function (value){
        return Array.isArray( value )
    },
    isFunction(value){
        return typeof value === 'function'
    },
    /**
     * 最核心的方法,能夠在原型上擴展其餘方法,jq的·插件就是靠他擴展的
     * @param {*} obj1 
     * @param {*} obj2 
     * 兩個參數則是將後一個對象合併到前一個
     * 一個參數表明將對象拷貝到$的原型或者實例上
     */
    extend(obj1,obj2){
        var target;
        var clone;
        var copy;
        var src;
        target = obj2 ? obj1 : this;
        if(!obj2){
            obj2 = obj1;
        }
        for(var name in obj2){
            copy = obj2[name]
            src = target[name]
            if(typeof copy === 'object'){//若是須要複製的屬性是對象類型
                if(this.isObject(copy)){
                    clone = src && isObject(src) ? src : {}
                }else if(this.isArray(copy)){//當屬性爲數組的時候
                    clone = src && this.isArray(src) ? src : []
                }
                target[name] = this.extend(clone,copy)
            }else{
                if(copy){
                    target[name] = copy
                }
            }
        }
        return target;
    },   
    /**
     * 循環jq的元素,callback實現循環中須要的操做
     */
    each:function (callback){
        for (var i = 0;i<this.length;i++){
            callback(this[i])
        }
    },
    /**
     * 3種狀況
     * 1.css('width','200px')                     設置一個
     * 2.css({'width':'200px','height':'300px'})  設置一羣
     * 3.css('width')                             獲取
     */
    css:function(key,value){
        return $.access(this, key, value, function(elem,key,value){
            //value存在就設置屬性,不存在就獲取屬性
            return value ? $.setStyle(elem,key,value) : $.getStyle(elem,key)
        })
    },
    /**
     * 3種狀況
     * 1.attr('data-id','name')                      設置一個
     * 2.attr({'data-key':'0000','data-id':'name'})  設置一羣
     * 3.attr('data-id')                               獲取
     */
    attr(key,value){
        return $.access(this, key, value, function(elem,key,value) {
            return value ? $.setAttr(elem,key,value) : $.getAttr(elem,key)
        })
    },
    /**
     *設置元素的width,沒有參數且選擇器選擇元素惟一時候返回元素的width
     */
    width:function(params){
        if(params){
            this.each(function(item){
                item.style['width'] = params + 'px'
            })
        }else if(!params && this.length===1){
            return this.getStyle(this[0],'width')
        }
    },
    /**
     * 入棧操做,棧的最上方的最早出來,返回一個新的jq對象,保存前一個
     * $('#app').pushStack(document.querySelector('li')).css({background:'red'})
     * 那麼此時只是li顏色變化
     * 使用end()方法,回到前一個jq對象
     */
    pushStack: function( elems ) {
        var ret = $.merge( this.constructor(), elems );
        ret.prevObject = this;
        return ret;
    },
    /**
     * 返回前一個jq對象,如今棧的底下一個棧
     */
    end: function() {
        if(this.prevObject){
            return this.prevObject
        }else{
            return this;
        }
    },
    /**
     * 循環jq對象自身,對每一個匹配到的元素作操做
     */
    map: function( callback ) {
        return this.pushStack( $.map( this, function( elem, i ) {
            return callback.call( elem, i, elem );
        } ) );
    },
    ready: function(event){
        var domReady = new Defferd()
        domReady.push(event)
        document.addEventListener('DOMContentLoaded', function() {
            domReady.done()
        })
    }

}
$.prototype.init.prototype = $.prototype;
$.extend = $.prototype.extend;
/**
 * 解析html
 */
$.extend({
    parseHTML:function(ele){
        //匹配<li>111</li><li>222</li>
        var regx = /<(\w+)>(\w+)<\/\w+>/g;
        var obj={}
        var i=0;
        while(true){
            var item = regx.exec(ele)
            console.log(item)
            if(!item){
                break
            }else{
                obj[i] = document.createElement(item[1])
                obj[i].innerHTML = item[2]
                i++;
            }
        }
        return obj;
    }
})
$.extend({
    grep: function( elems, callback, inv ) {
        var ret = [], retVal;
        inv = !!inv;//轉成真正的布爾類型,對否反選的操做
        for ( var i = 0, length = elems.length; i < length; i++ ) {
            // 這裏callback的參數列表爲:value, index,與each的習慣一致
            retVal = !!callback( elems[ i ], i );
            // 是否反向選擇
            if ( inv !== retVal ) {
                ret.push( elems[ i ] );
            }
        }
        return ret;
    },
})
/**
 * jq真正的遍歷方法,上面的each是我寫的比較簡單
 * 能夠將每一個回調函數的this指向遍歷的元素自己,因而能夠在回調內部使用this
 */
$.extend({
    jqEach: function( object, callback) {
        var name;
        for ( name in object ) {
            //將this的指向指爲每一個遍歷的元素對象
            //因此在遍歷dom元素時候,內部可使用$(this)來生成相應的jq對象
            if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
                break;
            }
        }
    },
})
/**
 * map方法,返回的是對數組的每一項作處理,‘
 * 返回一個新的數組爲處理後的數組
 * jq內部能夠處理對象,這裏作了簡化不能處理對象,只是處理數組
 */
$.extend({
    map: function( arr, callback) {
        var i = 0;
        var ret = [];
        var length = arr.length;
        for ( ; i < length; i++ ) {
            // 執行callback,參數依次爲value, index, arg
            value = callback( arr[ i ], i);
            // 若是返回null,則忽略(無返回值的function會返回undefined)
            if ( value != null ) {
                ret[ ret.length ] = value;
            }
        }
        return ret;
    }
})
$.extend({
    merge: function( first, second ) {
        var len = +second.length,
            j = 0,
            i = first.length;

        for ( ; j < len; j++ ) {
            first[ i++ ] = second[ j ];
        }

        first.length = i;

        return first;
    },
})

$.extend({
    access: function( elems, key,value ,fn) {
        //console.log(key)
        var i = 0;
        var length = elems.length;
        /**
         * key是對象
         * {
         *   width:200px;
         *   background:'red'
         * }
         */
        if($.prototype.isObject(key)){
            for (var k in key){
                console.log(k,key[k])
                $.access(elems,k,key[k],fn)
            }
            return elems;
        }
        /**
         * key ,value都存在,給每一個元素執行方法,好比css每一個元素綁定樣式
         */
        if(value){
            for(;i<length;i++){
                fn(elems[i],key,value)
            }
            return elems
        }
        /**
         * value不存在就是獲取,好比獲取樣式
         */
        return length > 0?fn(elems[0],key) : undefined;
    },
})
$.extend({
    //獲取樣式
    getStyle:function (element, property){
        var proValue = null;
        if (!document.defaultView) {
            proValue = element.currentStyle[property];
        } else {
            proValue = document.defaultView.getComputedStyle(element)[property];
        }
        return proValue;
    },
    //設置樣式
    setStyle: function (ele,key,value) {
        ele.style[key] = value;
    },
    //獲取自定義屬性
    getAttr: function (element, property) {
        return element.getAttribute(property); //獲取
    },
    //設置自定義屬性
    setAttr: function (ele,key,value) {
        ele.setAttribute(key,value)
    }
    
})
/**
 * 延遲對象
 * push是在對象放入方法
 * done是執行該對象隊列中全部的方法
 */
// function Defferd(){
//     this.events = []
//     this.push = function(event){
//         this.events.push(event)
//     }
//     this.done = function(){
//         for(var i = 0; i < this.events.length; i++){
//             this.events[i]()
//         }
//     }
// }

/**
 * 回調對象實現 -- 在不少時候須要控制一系列的函數順序執行。那麼通常就須要一個隊列函數來處理這個問題
 * list保存回調函數
 * fire執行回調函數
 * 與正真的jq callback差距很大,包括能夠中止,能夠清除等等
 */
$.extend({
    Callback: function (option) {
        option = option || {}
        var list = []
        var self = {
            add: function ( fn ) {
                if( Object.prototype.toString.call( fn )==='[object Function]' ){
                    /*
                        不存在unique,直接push
                        存在unique,看後面是否成立
                    */
                    if( !option.unique || !list.includes(fn)){
                        list.push( fn )
                    }
                    
                }
                console.log(this)
                return this;
            },
            fire: function ( args ){
                list.forEach( function ( fn ) {
                    fn( args )
                } )
            }
        }
        return self;
    }
})

/**
 * 延遲對象
 * var d = $.Defferd()
 * d.done(function(e){}).fail(function(e){})
 * d.resolve('haha')
 * 
 */
$.extend({
    Defferd: function () {
        var tuples = [
            ['resolve','done',Callback()],
            ['reject','fail',Callback()]
        ]
        var defferd = {}
        tuples.forEach( function ( tuple ) {
            var list = tuple[2]
            defferd[tuple[1]] = list.add
            defferd[tuple[0]] = list.fire
        } )
        return defferd;
    }
})

$.extend({
    error: function ( msg ) {
       throw new Error( msg )
    }
})

/**
 * 數據緩存
 */
function  Data(){
    this.cache = {}//存儲數據的地方
    this.expando = 'JQuery'+ Math.random()
}

Data.uid = 1;
//獲取元素對應的key,key是元素跟this.cache的映射
Data.prototype.key = function( owner ){
    var unlock = owner[ this.expando ]
    if( !unlock ){//key不存在則給元素加自定義屬性'JQuery'+ Math.random() = ‘key’
        unlock = Data.uid++
        owner[ this.expando ] = unlock;
    }
    if( !this.cache[ unlock ] ){//在cache中的key不存在則分配一個空對象
        this.cache[ unlock ] = {}
    }
    return unlock;//返回對應的key
}
/**
 * 
 * @param {HTMLEle} owner html元素
 * @param {string} key    存儲的key
 * @param {string} value  存儲的value
 */
Data.prototype.set = function( owner,key,value ){
    var unlock = this.key( owner )
    var cache = this.cache[ unlock ]
    if( typeof key === 'string'){
        cache[ key ] = value
    }
}
/**
 * 
 * @param {HTMLEle} owner html元素
 * @param {string} key 獲取的key,能夠不存在則返回該元素全部緩存
 */
Data.prototype.get = function( owner,key ){
    var unlock = this.key( owner )
    var cache = this.cache[ unlock ]
    if( key ){
        return cache[ key ]
    }
    return cache;
}
/**
 * 
 * @param {HTMLEle} owner html元素
 * @param {string} key    設置或者獲取的key,跟value一同不存在則返回該元素全部緩存
 * @param {string} value  設置的value,不存早則就是內部調用get,存在內部調用set
 */
Data.prototype.access = function( owner,key,value ){
    if( value ){
        return this.set( owner, key, value )
    }
    return this.get( owner, key )
}
var data_user = new Data()
//給JQ添加該工具方法
$.extend({
    data: data_user.access.bind( data_user )
})
$.extend({
    error: function ( msg ) {
       throw new Error( msg )
    }
})
View Code

 

出處:http://www.javashuo.com/article/p-okvphsqt-kh.html

======================================================

前面的話

  雖然jQuery已經日漸式微,但它裏面的許多思想,如選擇器、鏈式調用、方法函數化、取賦值合體等,有的已經變成了標準,有的一直影響到如今。因此,jQuery是一個偉大的前端框架。前端世界突飛猛進,因爲實在是沒有時間去精讀源碼,因而本身封裝一個簡易版本的jQuery,來梳理jQuery的核心思路

 

基本構架

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

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

  jquery幾大特徵:

  一、經過$()選擇的元素都是一個集合,即便僅僅是一個元素

  所以,建立一個elements屬性爲一個數組,去接收穫取的元素

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

  二、鏈式調用

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

 

$函數

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

  一、參數爲函數時,則直接運行

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

  二、參數爲對象時,則把DOM對象轉換爲$對象

$(document.body)

  三、參數爲字符串時,則根據字符串選擇出元素,並轉換爲$對象

$('#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> 
複製代碼

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

  

 

 

出處:https://www.cnblogs.com/xiaohuochai/p/7526278.html

相關文章
相關標籤/搜索