js學(xué)習(xí): 自定義類庫 - miniQuery 2.0

Paste_Image.png

在上一篇 零基礎(chǔ)打造自己的 js 類庫(1) 中岁经,原本只是為了寫個(gè)小案例朋沮,說明一下閉包,js對象的作用缀壤。

后來我隱約有一個(gè)想法樊拓,我是不是可以將miniQuery寫得更完善一些呢。我的意思是說塘慕,盡量使用jQuery的調(diào)用規(guī)則筋夏,看看自己能不能把常用的方法模擬出來?

這個(gè)想法產(chǎn)生以后图呢,我感覺挺興奮条篷,正好可以藉由這個(gè)機(jī)會把js的知識點(diǎn)再復(fù)習(xí)一下。

今后只要有時(shí)間蛤织,我就把miniQuery更新一下赴叹,添加新的api方法進(jìn)去。作為自己的一個(gè)學(xué)習(xí)記錄指蚜。

零基礎(chǔ)打造自己的 js 類庫(1) 寫完后乞巧,我又陸陸續(xù)續(xù)地改了很多代碼,繼而有了下面這個(gè)版本姚炕,暫且就叫做miniQuery v2.0吧,嘿嘿丢烘。

Paste_Image.png
Paste_Image.png

API方法目前大概分為 三個(gè)區(qū)域:

1. dom 相關(guān) : 主要獲取dom元素

2. css 相關(guān):給dom元素設(shè)置css樣式

3. 事件相關(guān) :給元素添加事件

4. 屬性相關(guān):對元素屬性進(jìn)行各種操作

5. 簡易u(yù)i : 額柱宦,目前只寫了一個(gè)按鈕

我利用零碎時(shí)間寫了一個(gè)禮拜,沒想到假模假式的也弄了不少方法了播瞳,當(dāng)然掸刊,這些肯定是遠(yuǎn)遠(yuǎn)不夠的。不夠以后寫案例的時(shí)候我差不多就可以直接調(diào)用這個(gè)miniQuery.js了赢乓,主要方便了自己忧侧,如果覺得有必要石窑,我就可以立即在里面添加新的方法,實(shí)現(xiàn)了訂制功能蚓炬。

當(dāng)然松逊,目前這個(gè)版本功能還比較少,bug估計(jì)還有很多肯夏,不過沒關(guān)系经宏,反正就搞著玩玩,出了問題自己背鍋就行了驯击。主要還是用于培養(yǎng)興趣烁兰,我本身不是做前端開發(fā)的,但是個(gè)人隱約感覺js在未來必定會火徊都,當(dāng)然現(xiàn)在也非常受歡迎了沪斟,我打算繼續(xù)學(xué)下去。

首先來看看miniQuery怎么使用吧暇矫。

來一個(gè)測試頁面主之,引入miniQuery

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <script type="text/javascript" src="js/miniQuery.js"></script>
        <title>測試頁面</title>
        <script type="text/javascript">
        
            window.onload = function(){
                
            }
            
        </script>
    </head>
    <body>
        <div class='box'></div>
    </body>
</html>

頁面上只畫了一個(gè)div,其他啥也沒有袱耽。

Paste_Image.png

div沒有寬高杀餐。

接下來,我們用miniQuery來拿到這個(gè)對象朱巨。

var $box = $('.box').eq(0);
console.log($box);
Paste_Image.png

可見史翘,返回的并不是一個(gè)dom對象,而是一個(gè)miniQuery對象冀续,具體的原理在上一節(jié)中已經(jīng)闡明琼讽。

OK,我們來給它定義寬高和背景色洪唐。

var $box = $('.box').eq(0);
$box.css({
    width : 80 ,
    height : 80 ,
    background : 'deeppink'
});

效果:

Paste_Image.png

我們在api上還看到有width钻蹬,height,backgroundColor方法凭需,而且miniQuery還支持鏈?zhǔn)秸{(diào)用问欠,所以能這么寫:

$box.height(80).width(80).backgroundColor('deeppink');

效果是一樣的。

然后粒蜈,我們給它添加一個(gè)事件顺献,當(dāng)點(diǎn)擊的時(shí)候就把顏色換為skyblue:

var $box = $('.box').eq(0);
$box.css({
    width : 80 ,
    height : 80 ,
    background : 'deeppink'
}).on('click',function(){
    this.css({
        background:'skyblue'
    });
});
123.gif

再來看一看簡單的ui。

我們來引入css文件:

<link rel="stylesheet" type="text/css" href="css/mui.css"/>
var $box = $('.box').eq(0);
$box.linkbutton();
Paste_Image.png

按鈕的樣式就出來了枯怖,然后我們來設(shè)置按鈕的屬性注整。

var $box = $('.box').eq(0);
$box.linkbutton({
    text : '保存' ,
    click : function(){
        alert('保存成功!');
    }
});
Paste_Image.png

按鈕的大小也自動(dòng)變大了。

123.gif

至于其他方法肿轨,我就不一一測試了寿冕,問題肯定還是有的,以后慢慢完善吧椒袍。

至于這個(gè)miniQuery的具體實(shí)現(xiàn)驼唱,以后有機(jī)會的話我再開貼記錄吧。

附上目前的源代碼:

mui.css

.linkbutton {
    padding: .4em .9em; /*em的好處就是隨著父元素的字體大小而變化槐沼,當(dāng)該元素的字體變化時(shí)曙蒸,會自適應(yīng)*/
    border: 1px solid rgba(0,0,0,.1);
    background-color: #ac0;
    border-radius: .2em;
    box-shadow: 0 1px 5px rgba(0,0,0,.5);
    color: #fff;
    text-shadow: 0 -.06em .24em rgba(0,0,0,.5); /*將陰影設(shè)置為半透明,就無所謂底色了岗钩,都能很好地適應(yīng)*/
    font-size: 130%; 
    line-height: 1.5; /*行高是字號的1.5倍*/
    display:inline-block;
    cursor:pointer;
    font-family: "微軟雅黑";
}
"use strict";

/**
 * miniQuery 和 工具類庫
 * 版本 2.0 (修正了一部分Bug纽窟,增加了一些方法)
 * 作者:剽悍一小兔
 */

// ------------------------ 基本擴(kuò)展, 字符串,數(shù)組等---------------------------------//
function extend_base (){
    
    if(!String.prototype.format ){
        String.prototype.format = function() {
            var e = arguments;
            return this.replace(/{(\d+)}/g,function(t, n) {
                return typeof e[n] != "undefined" ? e[n] : t
            })
        };
    }
    
    if (!Array.prototype.forEach && typeof Array.prototype.forEach !== "function") {
        Array.prototype.forEach = function(callback, context) {
           // 遍歷數(shù)組,在每一項(xiàng)上調(diào)用回調(diào)函數(shù),這里使用原生方法驗(yàn)證數(shù)組兼吓。
           if (Object.prototype.toString.call(this) === "[object Array]") {
               var i,len;
               //遍歷該數(shù)組所有的元素
               for (i = 0, len = this.length; i < len; i++) {
                   if (typeof callback === "function"  && Object.prototype.hasOwnProperty.call(this, i)) {
                       if (callback.call(context, this[i], i, this) === false) {
                           break; // or return;
                       }
                   }
               }
           }
        };
    }
    
    if(!String.prototype.format ){
        Array.isArray = function(obj){
            return obj.constructor.toString().indexOf('Array') != -1;
        }
    }
    
}


extend_base(); 


// ------------------------ 工具包---------------------------------//
var utils = {
            center : function(dom){
                dom.style.position = 'absolute';
                dom.style.top = '50%';
                dom.style.left = '50%';
                dom.style['margin-top'] = - dom.offsetHeight / 2 + 'px';
                dom.style['margin-left'] = - dom.offsetWidth / 2 + 'px';
            },
        
            /** dom相關(guān) * */
            isDom : ( typeof HTMLElement === 'object' ) ?
                function(obj){
                    return obj instanceof HTMLElement;
                } :
                function(obj){
                    return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string';
                } ,
             
            /** 數(shù)組相關(guān) * */
            isArray : function(obj){
                return obj.constructor.toString().indexOf('Array') != -1;
            }
            
        }
        


// ------------------------ miniQuery.js ---------------------------------//
;(function(win){
    
    var miniQuery = function(selector){
        var miniQuery = null;
        var length = 0;
        var children = [];
        if(!selector) return;
        
        /** 1. 傳入的是id * */
        if(selector.toString().indexOf('#') != -1) {
            selector = selector.replace('#','');
            miniQuery = document.getElementById(selector);
        } 
        
        /** 2. 傳入的是class * */
        else if(selector.toString().indexOf('.') != -1){
            selector = selector.replace('.','');
            miniQuery = document.getElementsByClassName(selector);
        }
        
        
        /** 3. 傳入的是dom元素 * */
        else if(utils.isDom(selector)){
            miniQuery = selector;
        }
        
        if(!miniQuery) return; //如果本類庫包裝不了臂港,就返回
        
        if(miniQuery.length){   //如果是一個(gè)類數(shù)組元素的話,就獲取他的長度
            length = miniQuery.length; 
        }else{
            length = 1; //這種情況视搏,說明成功包裹了元素审孽,但是該元素還是存在的,就將長度設(shè)定為1
        }
        
        children = miniQuery.children; //取得所有的孩子節(jié)點(diǎn)
        
        return {
            
            /** 屬性區(qū) */
            obj : miniQuery,    //返回的dom元素
            index : 0 ,         //默認(rèn)的角標(biāo)(假如 miniquery 是一個(gè)類數(shù)組的話)
            length : length,    //元素的個(gè)數(shù)(假如 miniquery 是一個(gè)類數(shù)組的話)
            children : children,//所有孩子節(jié)點(diǎn)
            
            
            /** 方法區(qū) */
            
            // ------------------------ dom 相關(guān) ---------------------------------//
            
            /**獲取dom對象本身,返回純粹的dom元素浑娜,而非miniQuery元素*/
            getObj : function(){
                return this.obj;
            } ,
            
            /**獲取元素的長度*/
            size : function(){
                return this.length;
            } ,
            
            /** 假如 miniquery 是一個(gè)類數(shù)組的話佑力,用于返回其中一個(gè)元素 */
            eq : function(index){
                if(length > 0) {
                    return $(this.obj[index]); //eq返回的還是miniQuery對象
                }else{
                    return null;
                }
            } ,
            
            /** 獲得第一個(gè)匹配元素 */
            first : function(){
                return $(this.obj[0]);
            } ,
            
            /** 獲得最后一個(gè)匹配元素 */
            last : function(){
                return $(this.obj[this.length - 1]);
            } ,
            
            /** 獲得最后一個(gè)匹配元素 */
            getChildren : function(){
                return this.obj.children;
            } ,
            
            /** 獲得某一個(gè)孩子節(jié)點(diǎn) */
            getChild : function(i){
                return $(this.children[i]);
            } ,
            
            /** 獲得父節(jié)點(diǎn) */
            getParent : function(){
                return $(this.obj.parentElement);
            } ,
            
            /** 獲得上一個(gè)節(jié)點(diǎn) */
            previous : function(){
                var parent = this.getParent();
                var children = parent.children;
                for(var i = 0; i < children.length; i++){
                    if(this.obj == children[i]) {
                        return $(children[i - 1]);
                    }
                }
                return null;
            } ,
            
            /** 獲得下一個(gè)節(jié)點(diǎn) */
            next : function(){
                var parent = this.getParent();
                var children = parent.children;
                for(var i = 0; i < children.length; i++){
                    if(this.obj == children[i]) {
                        return $(children[i + 1]);
                    }
                }
                return null;
            } ,
            
            findClassDom : function(className){
                 this.obj = this.obj.getElementsByClassName(className) ;
                 return this ;
            } ,
            
            findIdDom : function(id){
                 var $this = this; 
                 var children = this.getChildren();
                 children = Array.prototype.slice.call(children); //obj 轉(zhuǎn)  []
                 children.forEach(function(item){
                    //console.log(item.id);
                    (id === item.id) && ($this = item) ;
                 });
                 return this ;
            } ,
            
            // ------------------------ css 相關(guān) ---------------------------------//
            /** 添加背景色 */
            backgroundColor : function(color){
                this.obj.style.backgroundColor = color;
                return this;
            } ,
            
            /** 獲取style */
            getStyle : function(){
                var styleEle = null;
                if(window.getComputedStyle){
                    styleEle = window.getComputedStyle(this.obj,null);
                }else{
                    styleEle = ht.currentStyle;
                }
                return styleEle;
             } ,
            
            /** 設(shè)置或者拿到高度 */ 
            height : function(h){
                if(!h) return this.getStyle().getPropertyValue('height');
                (typeof h == 'number') && (h = h + 'px');
                this.obj.style.height = h;
                return this;
            } ,
            
            /** 設(shè)置或者拿到寬度 */ 
            width : function(w){
                if(!w) return this.getStyle().getPropertyValue('width');
                (typeof w == 'number') && (w = w + 'px');
                this.obj.style.width = w;
                return this;
            } ,
            
            /** 設(shè)置自定義樣式 */
            css : function(obj){
                if(!obj) return;
                for(var key in obj){
                    //console.log(key + '=========' + obj[key]);
                    this.obj.style[key] = typeof obj[key] === 'number' ? obj[key] + 'px' : obj[key];
                }
                return this;
            } ,
            
            /** 設(shè)置放大 倍數(shù)*/
            scale : function(scaleNumber){
                this.css({
                    scale : scaleNumber
                });
                return this;
            } ,
            
            
            hasClass : function(cls) {  
                return this.obj.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));  
            }  ,
            
            addClass : function(cls){
                if (!this.hasClass(cls)) this.obj.className += " " + cls;  
            } ,
            
            removeClass : function(cls) {  
                if (this.hasClass(cls)) {  
                    var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');  
                    this.obj.className = obj.className.replace(reg, ' ');  
                }  
            } ,
            
            toggleClass : function(cls){  
                if(this.hasClass(cls)){  
                    this.removeClass(cls);  
                }else{  
                    this.addClass(cls);  
                }  
            }  ,
            
            
            
            // ------------------------ 動(dòng)畫 相關(guān) ---------------------------------//
            
            //TODO
            animate : function(){
                
            } ,
            
            // ------------------------ 事件相關(guān) ---------------------------------//
            
            on : function(eventName,callback){
                var $this = this;
                this.obj['on' + eventName] = function(){
                    callback.call($this,$this.obj); //context指向$this,參數(shù)傳入dom對象
                };
                return this;
            } ,
            
            // ------------------------ 屬性相關(guān) ---------------------------------//
            
            attr : function(attr){
                return this.obj.attributes[attr];
            } ,
            
            
            // ------------------------ ui ---------------------------------//
            
            linkbutton : function(opts){
                var opts = opts || {};
                /**添加基本樣式* */
                this.addClass('linkbutton');
                this.on('mouseover' , function(e){
                    //console.log(e);
                    this.css({
                        backgroundColor: '#d4ef50'
                    });
                }).on('mouseout',function(e){
                    this.css({
                        backgroundColor: '#ac0'
                    });
                });
                
                opts.text && (this.obj.innerText = opts.text);
                opts.click && (this.on('click' , opts.click));
                
                
            }
            
            
            
        }
    }
    
    win.$ = miniQuery;
    
})(window);

我沒具體測試筋遭,如果發(fā)現(xiàn)目前代碼中的bug打颤,歡迎評論或者簡信我哦 _

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末漓滔,一起剝皮案震驚了整個(gè)濱河市编饺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌响驴,老刑警劉巖透且,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異豁鲤,居然都是意外死亡秽誊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門琳骡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锅论,“玉大人,你說我怎么就攤上這事日熬」餮幔” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵竖席,是天一觀的道長耘纱。 經(jīng)常有香客問我,道長毕荐,這世上最難降的妖魔是什么束析? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮憎亚,結(jié)果婚禮上员寇,老公的妹妹穿的比我還像新娘。我一直安慰自己第美,他們只是感情好蝶锋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著什往,像睡著了一般扳缕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上别威,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天躯舔,我揣著相機(jī)與錄音,去河邊找鬼省古。 笑死粥庄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的豺妓。 我是一名探鬼主播惜互,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼科侈!你這毒婦竟也來了载佳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤臀栈,失蹤者是張志新(化名)和其女友劉穎蔫慧,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體权薯,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡姑躲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盟蚣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片黍析。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖屎开,靈堂內(nèi)的尸體忽然破棺而出阐枣,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布蔼两,位于F島的核電站甩鳄,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏额划。R本人自食惡果不足惜妙啃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望俊戳。 院中可真熱鬧揖赴,春花似錦、人聲如沸抑胎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽阿逃。三九已至突倍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間盆昙,已是汗流浹背羽历。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留淡喜,地道東北人秕磷。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像炼团,于是被迫代替她去往敵國和親澎嚣。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案瘟芝? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,748評論 1 92
  • 前段時(shí)間各大社交軟件都被北美限定款星巴克的Unicorn刷屏易桃,身在北美的留學(xué)生一枚,我怎么可能不去趟這個(gè)渾水呢锌俱! ...
    Denise0112閱讀 196評論 0 0
  • 還是接著昨天的話題聊晤郑,Dreamweaver前面說我還在在學(xué)習(xí)階段,最近在mooc網(wǎng)贸宏,以及百度貼吧造寝,找到不少資源,...
    費(fèi)半仙閱讀 448評論 1 1
  • 老姐打來電話吭练,興奮的說:“你還記得恒恒奶奶家隔壁囡囡的姨婆嗎诫龙?” 我說記得。 “姨婆的丈夫鲫咽,就是那個(gè)新婚不久就離開...
    季靈閱讀 538評論 0 0