zoukankan      html  css  js  c++  java
  • JS----封装简易版jQuery

    自己封装简易版的Jquery

    (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;
    })(); 
  • 相关阅读:
    unity3d热更新插件uLua学习整理
    结合axios对项目中的api请求进行封装
    移动端适配剖析
    vscode如何调试node项目(给node项目打断点)
    mac上使用cnpm搭建npm私有仓库,并上传/下载私有npm包
    前端常见的兼容性问题--web端和移动端
    react树形选择组(支持:单选,多选,全选)
    MongoDB 与 Mysql 的对比
    使用div 的 contenteditable属性,实现输入编辑,输入 "#" 出现下拉选择
    前端单元测试,以及给现有的vue项目添加jest + Vue Test Utils的配置
  • 原文地址:https://www.cnblogs.com/e0yu/p/12860403.html
Copyright © 2011-2022 走看看