模拟jquery原理

;(function() {
        function JQuery(selector) {
          return new JQuery.prototype.init(selector)
        }

        JQuery.prototype.init = function(selector) {
          //返回的是一个类数组  this = {}
          this.length = 0
          let dom = null

          // 容错机制  如果传入的selector是一个空值,则返回的是 length=0 的空jq对象
          if (selector) {
            // '.dom' / '#dom'
            if (typeof selector == 'string') {
              if (selector.indexOf('.') != -1) {
                dom = document.getElementsByClassName(selector.slice(1))
              }
              if (selector.indexOf('#') != -1) {
                dom = document.getElementById(selector.slice(1))
              }
            }

            //两种方法判断是否时dom元素
            // 1.DOMElement nodeType  这种方法不可取 如果传入的selector是null就会报错
            // 2.selector instanceof Element (建议)如果传入的selector是null false
            // 用来接收之前返回的dom元素对象,比如 $('').eq(2) 这个返回的是一个dom元素

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

          return this
        }

        JQuery.prototype.css = function(attrObj) {
          for (let i = 0; i < this.length; i++) {
            for (let attr in attrObj) {
              this[i].style[attr] = attrObj[attr]
            }
          }
          return this
        }

        //get  0 1 2 / -1 -2 -3 返回的是一个dom
        //    / null  全部返回
        JQuery.prototype.get = function(index) {
          // if (index == null) {
          //   return [].slice.call(this, null)
          // } else {
          //   if (index >= 0) {
          //     return this[index]
          //   } else {
          //     return this[index + this.length]
          //   }
          // }
          return index == null
            ? [].slice.call(this, null)
            : index >= 0
            ? this[index]
            : this[index + this.length]
        }

        //eq  0 1 2 / -1 -2 -3 返回时jq对象
        //    null 返回一个空的jq对象
        JQuery.prototype.eq = function(index) {
          let dom =
            index == null
              ? null
              : index >= 0
              ? this[index]
              : this[index + this.length]
          return this.pushStack(dom)
        }

        //find  是在父级下查找子集元素
        // 参数 DOMElement  / string / jq对象  返回值是jq对象
        JQuery.prototype.find = function(config) {}

        //add
        JQuery.prototype.add = function(dom) {
          let curObejct = JQuery(dom), //传入需要合并的jq对象
            baseObject = this, // 当前的jq对象
            newObject = JQuery() //两者合并产生一个新的jq对象

          for (let i = 0; i < curObejct.length; i++) {
            newObject[newObject.length++] = curObejct[i]
          }

          for (let i = 0; i < baseObject.length; i++) {
            newObject[newObject.length++] = baseObject[i]
          }

          this.pushStack(newObject)
          return newObject //返回的是两者合并的新jq对象
        }

        //end  需要结束当前的操作,并且要返回到上一层操作,这个时候需要一个preventObject来存储这个上层的jq对象
        // 能返回的都需要存储一个preventObject对象,在jq中可以创建一个公用工具
        JQuery.prototype.end = function() {
          return this.preventObject
        }

        JQuery.prototype.pushStack = function(deom) {
          // end返回的都是一个jq对象,在preventObject中直接存储一个jq对象,
          // 需要判断deom是否是一个jq对象 不是需要转换为jq对象
          if (deom.constructor != JQuery) {
            deom = JQuery(deom)
          }
          deom.preventObject = this
          return deom
        }

        JQuery.prototype.init.prototype = JQuery.prototype

        window.$ = window.JQuery = JQuery
      })()
发布了45 篇原创文章 · 获赞 14 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/cmchenmei/article/details/87094283