VQuery-封装自己的JQuery

VQuery-封装自己的JQuery

标签(空格分隔): JS

封装自己的jQuery–vQuery

vQurey选择器

VQuery类

  • elements属性,存储选择的元素

参数

  • typeof的使用判断传入参数的类型

  • 字符串

    • class/id/tagname

函数

    • 事件绑定-

    • 对象

      • 直接插入

    //VQuery选择器
     function VQuery(vArg) {
        //用来保存选择的元素
        this.elements = [];
        switch (typeof vArg) {
            //当传入函数时.
        case "function":
            myAddEvent(window, "load", vArg);
            break;
        case "string":
            //传入字符串时.
            switch (vArg.charAt(0)) {
            case "#": //id
                var obj = document.getElementById(vArg.substring(1));
                this.elements.push(obj);
                break;
            case ".": //class
                this.elements = getByClassName(document, vArg.substring(1));
                break;
            default: //tagName
                this.elements = document.getElementsByTagName(vArg);
            }
            break;
        case "object":
            this.elements.push(vArg);
            break;
        }
    }
    

    VQuery事件

    绑定事件

    click方法.绑定点击事件

    /**
     * 元素点击方法
     * @param {Function} fn 点击后执行的函数
     */
    VQuery.prototype.click = function (fn) {
        for (var i = 0, len = this.elements.length; i < len; i++) {
            myAddEvent(this.elements[i], "click", fn);
        }
    };

    显示隐藏方法.hide/show.改变display属性

     /**
     * 显示元素,display:block
     */
    VQuery.prototype.show = function () {
        for (var i = 0, len = this.elements.length; i < len; i++) {
            this.elements[i].style.display = "block";
        }
    };
    /**
     * 隐藏元素,display:none
     */
    VQuery.prototype.hide = function () {
        for (var i = 0, len = this.elements.length; i < len; i++) {
            this.elements[i].style.display = "none";
        }
    };

    hover方法.鼠标移入移出时

    /**
     * 鼠标移入移出方法
     * @param {Function} fnOver 鼠标移入执行的函数
     * @param {Function} fnOut  鼠标移出执行的函数
     */
    VQuery.prototype.hover = function (fnOver, fnOut) {
        for (var i = 0, len = this.elements.length; i < len; i++) {
            myAddEvent(this.elements[i], "mouseover", fnOver);
            myAddEvent(this.elements[i], "mouseout", fnOut);
        }
    };

    toggle方法.切换

    • 点击记数

     //使用匿名函数包装器来给每个对象创建局部变量
    (function (obj) {
        var count = 0;
        myAddEvent(obj, "click", function () {
            alert(count++);
        });
    })(this.elements[i]);
    • arguments的使用

    • toggle方法,切换,接收任意个参数,不断在参数间循环.例:点击显示隐藏
      */
      VQuery.prototype.toggle = function () {
      var _arguments = arguments;
      for (var i = 0, len = this.elements.length; i < len; i++) {

         addToggle(this.elements[i]);

      }

      function addToggle(obj) {

         var count = 0;
         myAddEvent(obj, "click", function () {
             _arguments[count++ % _arguments.length].call(obj);
         });

      }
      };

    css方法, 设置或者获取样式

    • 简单形式 — 设置/获取

    • 获取计算后的样式

    /**
     * 设置与获取元素样式的方法:
     * 接受1个或者2个参数(1个参数时:返回传入属性名对应的的样式值,两个参数:为传入的样式名为设置样式值)
     * @param {String} attr  设置或获取的样式名
     * @param {String} value 样式值(可选)
     */
    VQuery.prototype.css = function (attr, value) {
        if (arguments.length == 2) {
            for (var i = 0, len = this.elements.length; i < len; i++) {
                this.elements[i].style[attr] = value;
            }
        } else {
            //1个参数时返回获取到的样式
            return getStyle(this.elements[0], attr);
    
        }
    };

    attr方法,设置或获取属性

     /**
     * 属性设置与获取方法,与css方法基本一致.
     * @param   {String} attr  设置或获取的属性名
     * @param   {String} value 属性值(可选)
     * @returns {String} 一个参数时,返回对应的属性值
     */
    VQuery.prototype.attr = function (attr, value) {
        if (arguments.length == 2) {
            for (var i = 0, len = this.elements.length; i < len; i++) {
                this.elements[i][attr] = value;
            }
        } else {
            return this.elements[0][attr];
        }
    
    }

    eq方法-减少匹配元素的集合为指定的索引的哪一个元素。

    /**取其中的第n个对象-方法-减少匹配元素的集合为指定的索引的哪一个元素。
     * @param   {Number} n 需要的第几个元素
     * @returns {Object} 返回获取到的vquery元素
     */
    VQuery.prototype.eq = function (n) {
        //必须使用$包装.使返回的节点从普通对象变得vquery的元素(普通对象没有vQuery方法)
    
        return $(this.elements[n]);
    };

    find方法-查找当前对象的后代元素.

    /**
     * 把arr2内的元素添加到arr1
     * 把类数组对象或数组转变为数组.(不需要类数组元素支持Array的方法)
     * @param {Array}  arr1 转变后的数组
     * @param {Object} arr2 类数组对象或数组
     */
    function appendArr(arr1, arr2) {
        for (var i = 0, len = arr2.length; i < len; i++) {
            arr1.push(arr2[i]);
        }
    }
    /**
     * 查找当前对象的后代元素.
     * @param   {String} str class名或标签名
     * @returns {Object} 获取到的对象集合
     */
     
    VQuery.prototype.find = function (str) {
        var aResult = [];
    
        for (var i = 0, len = this.elements.length; i < len; i++) {
            switch (str.charAt(0)) {
            case ".": //class
                var aEle = getByClassName(this.elements[i], str.substring(1));
                appendArr(aResult, aEle);
    
                break;
            default: //标签
                var aEle = this.elements[i].getElementsByTagName(str);
                //            aResult = aResult.concat[aEle];//这样做会出错,因为aEle并不是一个真正的数组,必须使用下面的方法
                appendArr(aResult, aEle);
            }
        }
        //必须这么做,因为不这样做返回的是节点集合,不具有VQuery的方法和属性
        var newVquery = $();
        newVquery.elements = aResult;
        return newVquery;
    };
    

    index方法–当前元素在其同级元素中的位置

    /**
     * 获取当前元素在同辈元素的位置
     * @param   {Object} obj 需要获取的对象
     * @returns {Number} 获取到的索引值
     */
    function getIndex(obj) {
        var aBrother = obj.parentNode.children;
        for (var i = 0, len = aBrother.length; i < len; i++) {
            if (aBrother[i] == obj) {
                return i;
            }
        }
    }
    /**返回相对于它同辈元素的位置的索引值。无参数
     * @returns {Number} 当前当前文档中其所在在位置,从0开始
     */
    VQuery.prototype.index = function () {
        return getIndex(this.elements[0]);
    };

    工具函数.

    $函数

    //函数包装器..可以不用new 了
    function $(vArg) {
        return new VQuery(vArg);
    }

    工具函数

    /**通过class类名来选取元素
     * @param   {Object} parent 父级对象,
     * @param   {String} sClass className类名
     * @returns {Array}  获取到的节点数组
     */
    function getByClassName(parent, sClass) {
        if (parent.getElementsByClassName) {
            return parent.getElementsByClassName(sClass);
        } else {
            var oEle = parent.getElementsByTagName("*"),
                arr = [],
                reg = new RegExp("\\b" + sClass + "\\b");
            for (var i = 0, len = oEle.length; i < len; i++) {
                if (reg.test(oEle[i].className)) {
                    arr.push(oEle[i]);
                }
            }
            return arr;
        }
    }
    /**
     *事件添加函数
     * @param {Object}   obj  需要绑定事件的对象
     * @param {String}   type 事件类型
     * @param {Function} fn   事件触发执行的函数
     */
    function myAddEvent(obj, type, fn) {
        //标准
        if (obj.addEventListener) {
            obj.addEventListener(type, fn, false);
        } else if (obj.attachEvent) {
            //IE
            obj.attachEvent("on" + type, function () {
                //修改ie下this指向window的问题
                fn.call(obj);
            });
        } else {
            //最后选择
            obj["on" + type] = fn;
        }
    }
        原文作者:三省吾身丶丶
        原文地址: https://segmentfault.com/a/1190000003997747
        本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
    点赞