직접 포장된 Starter jQuery

10387 단어 JavaScript
jQuery를 배운 지 곧 1년이 된다. jQuery를 배울 때 간단하고 쉬운 jQuery를 봉인한 적이 있다. 또한 자신이 원생 js에 대한 파악 정도를 고찰하기 위해서다.jQuery의 일부 기능을 실현했습니다.요소,add,trigger,queue,dequeue,delay,animate,callback,deffer...등의 방법Github 주소를 선택합니다.https://github.com/mytheart/my-projects/tree/master/projects/myjQuery
(function () {
    function jQuery (selector) {
        return new jQuery.prototype.init(selector);
    }
    jQuery.prototype.init = function (selector) {
        // this = {};
        //    dom      jQuery      
        // id class
        this.length = 0;
        // null undefined dom
        if (selector == null) {
            return this;
        }

        if (typeof selector == 'string' && selector.indexOf('.') != -1) {
            var dom = document.getElementsByClassName( selector.slice(1) );
        }else if (typeof selector == 'string' && selector.indexOf('#') != -1) {
            var dom = document.getElementById( selector.slice(1) );
        }

        if (selector instanceof Element || dom.length == undefined) {
            this[0] = dom || selector;
            this.length++;
        }else {
            //     
            for (var i = 0; i < dom.length; i++) {
                this[i] = dom[i];
                this.length++
            }
        }
        // return this;
    }

    jQuery.prototype.css = function (config) {
        //        dom
        //     
        for (var i = 0; i < this.length; i++) {
            for (var attr in config) {
                this[i].style[attr] = config[attr];
            }
        }

        //     
        return this;
    }

    jQuery.prototype.pushStack = function (dom) {
        // dom newObj
        if (dom.constructor != jQuery) {
            dom = jQuery(dom);
        }
        dom.prevObject = this;
        return dom;
    }


    jQuery.prototype.get = function (num) {
        return num != null ? (num >= 0 ? this[num] : this[num + this.length]) : [].slice.call(this, 0);
    }

    jQuery.prototype.eq = function (num) {
        var dom = num != null ? (num >= 0 ? this[num] : this[num + this.length]) : null;
        return this.pushStack(dom);
    }

    jQuery.prototype.add = function (selector) {
        var curObj = jQuery(selector);
        var baseObj = this;
        var newObj = jQuery();

        for (var i = 0; i < curObj.length; i++) {
            newObj[newObj.length++] = curObj[i];
        }
        for (var i = 0; i < baseObj.length; i++) {
            newObj[newObj.length++] = baseObj[i];
        }

        console.log(newObj);

        this.pushStack(newObj);

        return newObj;
    }

    jQuery.prototype.end = function () {
        return this.prevObject;
    }


    jQuery.prototype.myOn = function (type, handle) {
        for (var i = 0; i < this.length; i++) {
            if (!this[i].cacheEvent) {
                this[i].cacheEvent = {};
            }
            if ( !this[i].cacheEvent[type] ) {
                this[i].cacheEvent[type] = [handle];
            }else {
                this[i].cacheEvent[type].push(handle);
            }
        }
    }

    jQuery.prototype.myTrigger = function (type) {
        var params = arguments.length > 1 ? [].slice.call(arguments, 1) : [];
        var self = this;
        for (var i = 0; i < this.length; i++) {
            if ( this[i].cacheEvent[type] ) {
                this[i].cacheEvent[type].forEach(function (ele, index) {
                    ele.apply(self, params)
                });
            }
        }
    }

    jQuery.prototype.myQueue = function () {
        var queueObj = this;
        var queueName = arguments[0] || 'fx';
        var addFunc = arguments[1] || null;
        var len = arguments.length;

        //     
        if (len == 1) {
            return  queueObj[0][queueName];
        }

        // queue dom {chain: }                  
        queueObj[0][queueName] == undefined ? queueObj[0][queueName] = [addFunc] : queueObj[0][queueName].push(addFunc);
        return this;
    }

    jQuery.prototype.myDequeue = function (type) {
        var self = this;
        var queueName = arguments[0] || 'fx';
        var queueArr = this.myQueue(queueName);
        var currFunc = queueArr.shift();
        if (currFunc == undefined) {
            return;
        }
        var next =  function () {
            self.myDequeue(queueName);
        }
        currFunc(next);
        return this;
    }

    jQuery.prototype.myDelay = function (duration) {
        var queueArr = this[0]['fx'];
        queueArr.push(function (next) {
            setTimeout(function () {
                next();
            }, duration);
        });
        return this;
    }


    jQuery.prototype.myAnimate = function (json, callback) {
        var len = this.length;
        var self = this;
        //              

        var baseFunc = function (next) {
            var times = 0;
            for (var i = 0; i < len; i++) {
                startMove(self[i], json, function () {
                    times++;
                    if (times == len) {
                        callback && callback();
                        next();
                    }
                });
            }
        }        

        this.myQueue('fx', baseFunc);

        if ( this.myQueue('fx').length == 1 ) {
            this.myDequeue('fx');
        }


        function getStyle (obj, attr) {
            if (obj.currentStyle) {
                return obj.currentStyle[attr];
            }else {
                return window.getComputedStyle(obj,false)[attr];
            }
        }
                
        function startMove (obj, json, callblack) {
            clearInterval(obj.timer);
            var iSpeed;
            var iCur;
            var name;
            obj.timer = setInterval(function () {
                var bStop = true;
                for (var attr in json) {                            
                    if (attr === 'opacity') {                                
                        name = attr;
                        iCur = parseFloat(getStyle(obj, attr)) * 100;
                    }else {
                        iCur = parseInt(getStyle(obj, attr));
                    }                            
                    iSpeed = (json[attr] - iCur) / 7;
                    if (iSpeed > 0) {
                        iSpeed = Math.ceil(iSpeed);
                    }else {
                        iSpeed = Math.floor(iSpeed);
                    }
                    if (attr === 'opacity') {
                        obj.style.opacity = (iCur + iSpeed) / 100;
                    }else {
                        obj.style[attr] = iCur + iSpeed + 'px';
                    }
                    if (json[attr] - iCur !== 0) {
                        bStop = false;
                    }
                }
                if (bStop) {
                    clearInterval(obj.timer);
                    callblack();
                }
            }, 30);
        }

        return this;   
    }



    jQuery.myCallbacks = function () {
        // 'once' 'memory' 'once memory' null
        //     
        var options = arguments[0] || '';
        //   add       
        var list = [];
        //              
        var fireIndex = 0;
        //       fire 
        var fired = false;
        //       
        var args = [];
        
        var fire = function () {
            for (; fireIndex < list.length; fireIndex++) {
                list[fireIndex].apply(window, args);
            }
            if (options.indexOf('once') != -1) {
                list = [];
                fireIndex = 0;
            }
        }


        return {
            add: function (func) {
                list.push(func);
                if (options.indexOf('memory') != -1 && fired) {
                    fire();
                }
                return this;
            },
            fire: function () {
               fireIndex = 0;
               args = arguments;
               fired = true;
               fire();
            }
        }
    }


    jQuery.myDeferred = function () {
        // callback 
        // 3 callback
        // done resolve    fail reject     progress notify
        var arr = [
            [
                jQuery.myCallbacks('once memory'), 'done', 'resolve'
            ],[
                jQuery.myCallbacks('once memory'), 'fail', 'reject'
            ],[
                jQuery.myCallbacks('memory'), 'progress', 'notify'
            ]
        ];

        var pendding = true;

        var deferred = {};

        for (var i = 0; i < arr.length; i++) {
            // arr[0][1]

            //   
            // deferred['done'] = function () {}
            // deferred['fail'] = function () {}
            // deferred['progress'] = function () {}
            deferred[ arr[i][1] ] = (function (index) {
                return function (func) {
                    arr[index][0].add(func)
                }
            })(i);

            //   
            // deferred['resolve'] = function () {}
            // deferred['reject'] = function () {}
            // deferred['notify'] = function () {}

            deferred[ arr[i][2] ] =  (function (index) {
               return function () {
                    var args = arguments;
                    if (pendding) {
                        arr[index][0].fire.apply(window, args);
                        arr[index][2] == 'resolve' || arr[index][2] == 'reject' ? pendding = false : '';
                    }
                    
               }
            })(i);
        }


        return deferred;
    }


    jQuery.prototype.init.prototype = jQuery.prototype;
    window.$ = window.jQuery = jQuery;
})();

jQuery 부분 기능만 썼고 부족한 점이 있으면 환영합니다. 여러분들이 계속 보완하는 것도 환영합니다.현재 많은 사람들이 jQuery는 이미 유행이 지났다고 말한다. js를 배운 후에 바로 3대 틀로 달려간다.그러나 나는 jQuery가 여전히 자신만의 매력을 가지고 있고 아직도 많은 회사들이 jQuery를 사용하고 있다고 생각한다.내가 간이판 jQuery를 포장한 취지도 어쿠스틱 js에 대한 나의 이해를 깊이 있게 하기 위해서였다.프레임이 어떻게 변하든 앞부분이 남아 있으면 원래 자바스크립트는 영원히 유행을 타지 않는다.

좋은 웹페이지 즐겨찾기