小微型库(1.获取元素的API)

178 阅读2分钟

参考JQ,利用原生js做一个简单的微型库,有以下一些功能:

  1. 可进行链式操作
  2. 元素的获取的API
    • id
    • class
    • tag标签名
    • css选择器
  3. 事件的处理
    • 事件的绑定兼容
    • 解绑事件的兼容
  4. typeOf 功能实现
  5. 封装遍历对象{}的方法
  6. 封装innerHTML方法
  7. 封装innerText方法
  8. 封装类名添加
  9. 封装类名移除
  10. 封装一个检测类名的方法:参考classList.toggle()
  11. 封装添加节点的方法
  12. 封装移除节点的方法
  13. 封装css样式设置的方法
  14. 封装操纵标签属性的方法

兼容到ie8


以上为要求,接下来一部分一部分实现.

第一部分 获取元素的API

  •  接口API:      $()
    
  •  ID选择器:     $("#id")
    
  •  class选择器 : $(".class")  注: 做兼容
    
  •  css选择器   : $("warp > div")
    
  •  标签选择器  : $("div")
    
  •  标签创建器  : $("<div>liang<span>sheng</span></div>")
    
(function(window, document, undefined) {
  //getElementsByClassName的兼容
  if (!document.getElementsByClassName) {
    //将 undefined时取反,能进来这里一定是IE低版本
    document.getElementsByClassName = function(eleClassName) {
      var aEle = document.getElementsByTagName("*"), //通配符,获得所有的标签
          reg = new RegExp("\\b" + eleClassName + "\\b"),
          arrEle = [];
      for (var i = 0, len = aEle.length; i < len; i++) {
        if (reg.test(aEle[i].className)) {
          arrEle.push(aEle[i]);
        }
      }
      return arrEle;
    };
  }

  //去空格的兼容,trim()在String的原型上,不兼容ie8及以下
  if(!String.prototype.trim){
    String.prototype.trim = function(){//谁调用trim 就指向谁
      return this.replace(/(^\s+)|(\s+$)/g, "");
    };
  }

  //工具类
  function Liang(selector) {
    return new Liang.prototype.init(selector);
  }
  Liang.prototype = {
    constructor: Liang,
    init: function(selector) {
      /* 初始化,获取元素,返回对象*/
      var arr = null,
          obj = {
            id: function(sel) {
              //id返回的有两种 null和节点
              //$("#id"),要进行字符串截取将#截掉
              var dom = document.getElementById(sel.slice(1));
              return dom === null ? [] : [dom];
            },
            className: function(sel) {
              //$(".className")
              return document.getElementsByClassName(sel.slice(1));
            },
            tag: function(sel) {
              //$("div")
              return document.getElementsByTagName(sel);
            },
            html: function(sel) {
              //创建元素
              var div = document.createElement("div");
              div.innerHTML = sel;
              return div.children;
            },
            css3: function(sel) {
              return document.querySelectorAll(sel);
            }
          };
      
      //判断参数的类型
      if(typeof selector === "string"){
        //进来的是选择条件
        selector = selector.trim();//去字符串首尾的空格
        //判断函数
        function isSelector(str){
          //str 就是选择条件的字符串
          if( /^</.test(str) ){ //以尖括号为开头的一定是创建标签
              return "html";
          }else if( /[+~>\s]/.test(str) ){ //css3选择器
              return "css3";
          }else if( /^\./.test(str) ){ //单个类名获取
              return "className";
          }else if( /^#/.test(str) ){ //id
              return "id";
          }else if( /^\w+$/.test(str) ){ //标签(任意字符)
              return "tag";
          }
        }
        arr = obj[isSelector(selector)](selector);
      } else if(typeof selector === "object"){
        //进来的是节点
        arr = [selector];
      }   
       Liang.each(arr, function(v, i){
          this[i] = v;
        }, this); //this修改为指向实例对象
       this.length = arr.length;
    },
  };
  //关键代码: 设置init的原型 = Liang类的原型,可以使得init访问到Liang的原型
  Liang.prototype.init.prototype = Liang.prototype;
  
  //静态方法
  //遍历
  Liang.each = function(obj, fn, that) {
    // 遍历对象  回调函数   可选参数,改变this指向的对象
    for (var i = 0, len = obj.length; i < len; i++) {
      var bool = fn.call(that || obj[i], obj[i], i, obj);
      if (bool === false) {
        break;
      } else if (bool === true) {
        continue;
      }
      /* false : 结束整个for循环  true : 跳出本次for循环 */
    }
  };
  //设置$为全局window的属性
  window.$ = Liang;
})(window, document, undefined);