2017.12.9-学习笔记:简易的jQuery封装

2017.12.9-学习笔记:简易的jQuery封装_第1张图片

前言
        本文有利于理解 jQuery 的原理,以及对构造函数、原型的理解,以下为简易的 jQuery 封装,如果想封装自己的函数方法库,可以参考这种思想。

步骤:

  • 1.沙箱(传一个window进去,为了对外暴露变量)

  • 2.定义jQuery的构造函数

  • 3.对外暴露jQuery构造函数,赋值给$,对外暴露$

  • 4.给jQuery原型添加方法,因为有很多方法,所以直接替换jQuery的原型对象

// 原型对象属性
constructor: jQuery,// 指定构造函数
jquery: '1.0.0',//jQuery版本
extend:function(){}// 扩展方法
  • 5.参数:选择器,传递进来,jQuery就会去获取页面中对应的元素
    把获取到的页面中所有的元素添加到jQuery对象中

  • 6.利用工厂函数返回 new 构造函数,解决每次都要写 new 的问题,实际的构造函数是 init,jQuery 只是工厂函数

  • 7.但是换了构造函数后就不能用jQuery原型上的方法了,所以也要把init的原型替换

  • 8.为了让外部能访问jQuery真正的构造函数,所以把init绑定到jQuery的原型上

  • 9.jQuery 的方法是分模块的,所以给原型添加一个扩展的方法extend,传入一个对象obj,函数能把对象obj中所有的方法都加入到原型中,在原型外调用extend方法,传入不同功能的对象即可

  • 10.因为在使用时是方法调用模式,所以所有方法里的this就指向jQuery对象

  • 11.使用时直接引用下面代码的js文件即可

代码:

// 沙箱模式
(function(window, undefined) {
  // 定义jQuery的构造函数
  // 参数:选择器,传递进来,jQuery就会去获取页面中对应的元素
  // 实际是工厂函数
  var jQuery = function(selector) {
    return new jQuery.fn.init(selector);
  }

  // 替换jQuery的原型对象
  jQuery.fn = jQuery.prototype = {
    constructor: jQuery,
    jquery: '1.0.0', //jQuery版本
    // 扩展方法:把obj中所有的方法都加入到原型中
    extend: function(obj) {
      for (var k in obj) {
        this[k] = obj[k];
      }
    }
  }

  // jQuery 真正的构造函数  把init方法绑定到jQuery的原型上
  var init = jQuery.fn.init = function(selector) {
    var elements = document.querySelectorAll(selector);

    // 把获取到的页面中所有的元素添加到jQuery对象中。
    // 方法1
    // for (var i = 0; i < elements.length; i++) {
    //   this[i] = elements[i];
    // }
    // this.length = elements.length;

    // 方法2  借用了数组的push方法,把数组中所有的元素都添加到this中
    // [].push.apply(this,elements);
    // 如果用call,就要用es6扩展运算符将伪数组转为参数序列
    [].push.call(this, ...elements);
  }

  // 让构造函数init的原型也指向jQuery的原型
  init.prototype = jQuery.fn;

  // 样式模块 css  addClass removeClass  toggleClass  hasClass
  jQuery.fn.extend({
    css: function() {
      // 如果传进的参数是两个,就是设置
      if (arguments.length === 2) {
        // 参数1为样式名,参数2为样式值
        var name = arguments[0];
        var value = arguments[1];
        // 给所有的jQuery对象设置传进来的样式
        for (var i = 0; i < this.length; i++) {
          this[i].style[name] = value;
        }
      };
      // 如果传进的参数是一个,如果该参数是字符串,是获取,如果是对象,就是设置
      if (arguments.length === 1) {
        var temp = arguments[0];
        if (typeof temp === "object") {
          // 给this中所有的元素设置多个样式
          for (var i = 0; i < this.length; i++) {
            // 遍历传进来的对象
            for (var k in temp) {
              this[i].style[k] = temp[k];
            }
          }
        };
        if (typeof temp === "string") {
          //获取行内样式
          //return this[0].style[temp];
          //获取计算后的样式
          return window.getComputedStyle(this[0])[temp];
        }
      }
      // 链式编程,返回这个jQuery对象
      return this;
    },
    addClass: function(name) {
      // 这里的this指向调用该方法的jQuery对象
      for (var i = 0; i < this.length; i++) {
        // 利用h5的新属性classList给所有的jQuery对象添加该类名
        this[i].classList.add(name);
      }
      // 链式编程,返回这个jQuery对象
      return this;
    },
    removeClass: function(name) {
      for (var i = 0; i < this.length; i++) {
        this[i].classList.remove(name);
      }
      return this;
    },
    toggleClass: function(name) {
      for (var i = 0; i < this.length; i++) {
        this[i].classList.toggle(name);
      }
      return this;
    },
    hasClass: function(name) {
      for (var i = 0; i < this.length; i++) {
        return this[i].classList.contains(name) ? true : false;
      }
    }
  });

  //节点模块...等等
  jQuery.fn.extend({
    next: function() {},
    prev: function() {},
    siblings: function() {},
    prevAll: function() {},
    nextAll: function() {},
    parent: function() {}
  })

  // 对外暴露$和jQuery
  window.$ = window.jQuery = jQuery;
})(window);



2017.12.9-学习笔记:简易的jQuery封装_第2张图片


Knowledge changes the mind

你可能感兴趣的:(2017.12.9-学习笔记:简易的jQuery封装)