>

仿照jQuery写一个关于选择器的框架,带了注释

- 编辑:正版管家婆马报彩图 -

仿照jQuery写一个关于选择器的框架,带了注释

效仿jQuery写二个有关选择器的框架(带了疏解,请多多帮衬~),jquery选择器

var select = (function () {
  //那是多个至极与捕获的代码,它代表的情趣是:若是push方法现身了不当那么就供给重写push方法
  try {
    //那边是投机模仿二个地方,来利用系统的push方法,假如能够完毕的话就证实系统帮忙push方法
    //这种措施是系统手艺检查评定中的方法效果检查评定
    var div = document.createElement( 'div' );
    div.innerHTML = '<p></p>';
    var arr = [];
    push.apply( arr, div.getElementsByTagName( 'p' ));
  } catch ( e ) {
    //那边是当try里面包车型地铁push方法不实施的时候,会跻身这里面
    //在此面将push重新定义了弹指间,将其改为一个目的,那一个指标里面有二个push方法
    var push = {
      //将apply变成了push对象里面包车型大巴三个措施
      apply: function ( array1, array2 ) {
        for ( var i = 0; i < array2.length; i++ ) {
        //注意那边的赋值
        array1[ array1.length++ ] = array2[ i ];
        }
      }
    };
  }
  // 正则表明式
  //那句正则表明式是为着合营系统中是还是不是有自带的法子
  var rnative = /{s*[native/;
  var rtrim = /^s+|s+$/g;
  //那个是为着合营出 Id 类名 通配符 标具名
  //              1        2    3    4
  var rbaseselector = /^(?:#([w-]+)|.([w-]+)|(*)|(w+))$/;
  // 基本函数, support 对象, 验证 qsa 与 byclass
  var support = {};
  //基本函数里面的壹天性格,实质上是为了看一下系统中是还是不是有该措施(使用正则来判别卡塔尔
  support.qsa = rnative.test( document.querySelectorAll + '' );
  //同上
  support.getElementsByClassName = rnative.test( document.getElementsByClassName + '' );
  support.trim = rnative.test( String.prototype.trim + '' );
  support.indexOf = rnative.test( Array.prototype.indexOf + '' );
  // 基本办法
  //封装了getElementsByClassName函数,那是为着消除宽容难点
  //传入多个参数,八个是className,另三个是node-->这么些node指的是从页面上的node元素起头查找那一个className
  function getByClassName ( className, node ) {
    //若无传到node的话就给它一个私下认可值:document
    node = node || document;
    //声Bellamy(Bellamy卡塔尔些变量
    var allElem, res = [], i;
    //首先做判定,假使系统有那些艺术会利用系统的
    if ( support.getElementsByClassName ) {
      //直接运用定义的push方法
      return push.apply(res,node.getElementsByClassName( className ));
    } else {
      allElem = node.getElementsByTagName( '*' );
      for ( i = 0; i < allElem.length; i++ ) {
      if ( allElem[ i ].className === className ) {
        res.push( allElem[ i ] );
        }
      }
    return res;
    }
  }
  // 自定义完成 trim 方法,该办法是将字符串中的内定的事物去掉
  var myTrim = function ( str ) {
    // 表示两端去空格, 然后重回去除空格的结果
    if ( support.trim ) {
      return str.trim();
    } else {
      // 自定义完成
      //那边是将rtrim调换来空字符串,就要空格去掉了
      return str.replace( rtrim, '' );
      }
    }
    //那边封装的是indexOf方法,传入八个参数,数组,要搜求的事物,要物色的东西在数组里面包车型大巴开头索引(从第多少个初始找卡塔尔
    var myIndexOf = function ( array, search, startIndex ) {
    //首先将引得赋值,若是传入了目录,那么就让从前的目录等于它,如果未有传到那么就让它从零开首找
    startIndex = startIndex || 0;
    //那边照旧先推断系统有未有这种格局
    if ( support.indexOf ) {
    //这里代表系统有这种艺术,那么就一向采取就OK了,将结果回到
      return array.indexOf( search, startIndex );
    } else {
      //若无的话,我们就协调动手封装叁个
      //对这一个数组进行一个遍历,遍历的初始值就是从startIndex早先
      for ( var i = startIndex; i < array.length; i++ ) {
      //决断一下,即使数组里面有值与要询问的值格外,那么就回去这一个索引值
      if ( array[ i ] === search ) {
        return i;
      }
    }
    //当遍历完成之后,借使依旧不曾找到的话,就回来-1
    return -1;
   }
  }
  //封装一个去重的函数,传入的参数是二个数组
  var unique = function ( array ) {
    //声澳优(Ausnutria Hyproca卡塔 尔(阿拉伯语:قطر‎个空数组,用于收纳去重今后的因素
    var resArray = [], i = 0;
    //对传播的数组进行叁个遍历
    for ( ; i < array.length; i++ ) {
      //做叁个论断,假设说resArray里面未有arr里面包车型的士要素,则将arr里面包车型客车成分放到resArray里面
      //注意,那边使用的是事先封装好的myIndexOf方法
      if ( myIndexOf( resArray, array[ i ] ) == -1 ) {
        //使用的是前面封装好的push方法
      resArray.push( array[ i ] );
    }
  }
    //将以此数组重回
    return resArray;
  }
  //那边封装的是两种基本接纳器,ID选取器,类接纳器,通配符选用器,标签选取器
  function basicSelect ( selector, node ) {
    //那边的node指的是要在哪多少个底下去索求selector
    node = node || document;
    var m, res;
    if ( m = rbaseselector.exec( selector ) ) {
      if ( m[ 1 ] ) { // id选择器
        res = document.getElementById( m[ 1 ] );
        if ( res ) {//倘若res不是二个空的话,步向
          return [ res ];
        } else {//当res为空的话重临四个空数组
          return [];
        }
      } else if ( m[ 2 ] ) { // class选择器
        return getByClassName( m[ 2 ], node );
      } else if ( m[ 3 ] ) {//通配符选拔器
        return node.getElementsByTagName( m[ 3 ] );
      } else if ( m[ 4 ] ) {//标签选拔器
        return node.getElementsByTagName( m[ 4 ] );
      }
    }
      return [];
  }
  //封装多个构成选取器,这在这之中的标签使用逗号隔离的
  function select ( selector, results ) {
    results = results || [];
    var m, temp, selectors, i, subselector;
    //那边是假使传入的selector不是三个字符串的话,那么重回空数组
    if ( typeof selector != 'string' ) return results;
    // 评释参数都未有毛病, 接下来正是何等筛选
    // 首先剖断 qsa 是不是可用
    // 然后再 一步步的 自身达成
    if ( support.qsa ) {//假使系统有querySelectorAll方法,那么就接纳
    push.apply( results, document.querySelectorAll( selector ) );
    } else {
      // 荒诞不经再来考虑自个儿达成
      //首先将盛传的参数以逗号隔离,放到三个数组里面
      selectors = selector.split( ',' );
      // 循环遍历那几个数组
    for ( i = 0; i < selectors.length; i++ ) {
      //在这里个轮回之中对数组里面包车型大巴每二个要素进行多个删减空格的操作,保险数据是大家想要的款型
      subselector = myTrim( selectors[ i ] );
      // 接下来正是 管理 subselector,使用正则进行剖断
    if ( rbaseselector.test( subselector ) ) {
      // 基本选取器
      //借使相称到了就将相配到的流传到骨干的三种选用器函数只中,再次回到多个数组,将这一个数组进行三个push
    push.apply( results, basicSelect( subselector ) );
    } else {
      //假诺相配不到那么就使用 select2 函数
      select2( subselector, results );
      }
    }
  }
    // 再次来到 result注意,这么些数组要实行三个去重操作
    return unique( results );
  }
  //封装一个后人选拔器的函数,传入三个参数
  function select2 ( selector, results ) {
    results = results || [];
    //将以此参数以逗号隔离
    var selectors = selector.split( ' ' );
    //声贝拉米(Bellamy卡塔尔国(Karicare卡塔 尔(英语:State of Qatar)个数组,那几个数组用于贮存成分,以致三个node数组,这几个数组用于贮存从哪多少个成分开头找
    var arr = [], node = [ document ];
    for ( var j = 0; j < selectors.length; j++ ) {
      for ( var i = 0; i < node.length; i++ ) {
      //因为那边寻找的是后人选择器,所以只要找到最终边的并将其重临就能够了
      push.apply( arr, basicSelect( selectors[ j ], node[ i ] ));
      }
    //在终结的时候将arr里面包车型大巴值全体给node,要注意那时node里面包车型大巴值的功能是什么
    node = arr;
    //将arr清空
    arr = [];
    }
    //在最终将最后叁次获得到的node值赋给results
    //这里面包车型的士值是最后一遍取获得的要素,约等于说是要赢得的儿孙成分中的的末段四个成分
    push.apply( results, node );
    return results;
    }
    return select;
  })();

var select = (function () { //那是三个足够与捕获的代码,它表示的意思...

var select = (function () {
  //那是三个可怜与捕获的代码,它表示的意趣是:要是push方法现身了不当那么就须要重写push方法
  try {
    //那边是谐和模仿叁个气象,来采纳系统的push方法,假设能够完结的话就印证系统帮忙push方法
    //这种办法是系统技巧检查测量试验中的方法效果检查测验
    var div = document.createElement( 'div' );
    div.innerHTML = '<p></p>';
    var arr = [];
    push.apply( arr, div.getElementsByTagName( 'p' ));
  } catch ( e ) {
    //那边是当try里面包车型大巴push方法不实行的时候,会进来那中间
    //在此个大校push重新定义了须臾间,将其产生三个对象,那么些指标里面有一个push方法
    var push = {
      //将apply产生了push对象里面包车型客车三个艺术
      apply: function ( array1, array2 ) {
        for ( var i = 0; i < array2.length; i++ ) {
        //注意这边的赋值
        array1[ array1.length++ ] = array2[ i ];
        }
      }
    };
  }
  // 正则表明式
  //那句正则表达式是为了协作系统中是或不是有自带的措施
  var rnative = /{s*[native/;
  var rtrim = /^s+|s+$/g;
  //那个是为了合作出 Id 类名 通配符 标签名
  //              1        2    3    4
  var rbaseselector = /^(?:#([w-]+)|.([w-]+)|(*)|(w+))$/;
  // 基本函数, support 对象, 验证 qsa 与 byclass
  var support = {};
  //基本函数里面包车型大巴壹天性质,实质上是为着看一下体系中是不是有该办法(使用正则来决断卡塔尔
  support.qsa = rnative.test( document.querySelectorAll + '' );
  //同上
  support.getElementsByClassName = rnative.test( document.getElementsByClassName + '' );
  support.trim = rnative.test( String.prototype.trim + '' );
  support.indexOf = rnative.test( Array.prototype.indexOf + '' );
  // 基本办法
  //封装了getElementsByClassName函数,那是为了缓和宽容难题
  //传入八个参数,二个是className,另一个是node-->这么些node指的是从页面上的node成分开头查找那些className
  function getByClassName ( className, node ) {
    //若无传来node的话就给它三个暗中同意值:document
    node = node || document;
    //声爱他美些变量
    var allElem, res = [], i;
    //首先做推断,假设系统有其后生可畏法子会采用系统的
    if ( support.getElementsByClassName ) {
      //直接行使定义的push方法
      return push.apply(res,node.getElementsByClassName( className ));
    } else {
      allElem = node.getElementsByTagName( '*' );
      for ( i = 0; i < allElem.length; i++ ) {
      if ( allElem[ i ].className === className ) {
        res.push( allElem[ i ] );
        }
      }
    return res;
    }
  }
  // 自定义完成 trim 方法,该方法是将字符串中的钦点的东西去掉
  var myTrim = function ( str ) {
    // 表示两端去空格, 然后再次来到去除空格的结果
    if ( support.trim ) {
      return str.trim();
    } else {
      // 自定义达成
      //那边是将rtrim转产生空字符串,就要空格去掉了
      return str.replace( rtrim, '' );
      }
    }
    //那边封装的是indexOf方法,传入多个参数,数组,要物色的东西,要搜索的事物在数组里面包车型客车发端索引(从第多少个起来找卡塔 尔(英语:State of Qatar)
    var myIndexOf = function ( array, search, startIndex ) {
    //首先将引得赋值,借使传入了目录,那么就让起先的目录等于它,若无传来那么就让它从零先导找
    startIndex = startIndex || 0;
    //那边依然先决断系统有未有这种艺术
    if ( support.indexOf ) {
    //这里表示系统有这种办法,那么就直接运用就OK了,将结果再次来到
      return array.indexOf( search, startIndex );
    } else {
      //若无的话,大家就本身入手封装二个
      //对那些数组进行多个遍历,遍历的初叶值正是从startIndex开始
      for ( var i = startIndex; i < array.length; i++ ) {
      //判定一下,假设数组里面有值与要询问的值格外,那么就重临那些索引值
      if ( array[ i ] === search ) {
        return i;
      }
    }
    //当遍历实现之后,假如依旧尚未找到的话,就回到-1
    return -1;
   }
  }
  //封装三个去重的函数,传入的参数是几个数组
  var unique = function ( array ) {
    //声澳优(Ausnutria Hyproca卡塔尔国个空数组,用于收纳去重将来的因素
    var resArray = [], i = 0;
    //对传播的数组举行叁个遍历
    for ( ; i < array.length; i++ ) {
      //做四个料定,假诺说resArray里面未有arr里面包车型客车要素,则将arr里面包车型地铁元素放到resArray里面
      //注意,那边使用的是事先封装好的myIndexOf方法
      if ( myIndexOf( resArray, array[ i ] ) == -1 ) {
        //使用的是后面封装好的push方法
      resArray.push( array[ i ] );
    }
  }
    //将以此数组重返
    return resArray;
  }
  //那边封装的是多样基本选取器,ID采取器,类选取器,通配符接收器,标签接纳器
  function basicSelect ( selector, node ) {
    //那边的node指的是要在哪贰个底下去寻找selector
    node = node || document;
    var m, res;
    if ( m = rbaseselector.exec( selector ) ) {
      if ( m[ 1 ] ) { // id选择器
        res = document.getElementById( m[ 1 ] );
        if ( res ) {//借使res不是一个空的话,步入
          return [ res ];
        } else {//当res为空的话再次来到三个空数组
          return [];
        }
      } else if ( m[ 2 ] ) { // class选择器
        return getByClassName( m[ 2 ], node );
      } else if ( m[ 3 ] ) {//通配符选择器
        return node.getElementsByTagName( m[ 3 ] );
      } else if ( m[ 4 ] ) {//标签选择器
        return node.getElementsByTagName( m[ 4 ] );
      }
    }
      return [];
  }
  //封装一个结合采用器,这么些中的标签使用逗号隔开的
  function select ( selector, results ) {
    results = results || [];
    var m, temp, selectors, i, subselector;
    //那边是就算传入的selector不是多少个字符串的话,那么重返空数组
    if ( typeof selector != 'string' ) return results;
    // 注脚参数都不曾难题, 接下来就是什么样抉择
    // 首先剖断 qsa 是还是不是可用
    // 然后再 一步步的 本身完结
    if ( support.qsa ) {//假使系统有querySelectorAll方法,那么就采纳
    push.apply( results, document.querySelectorAll( selector ) );
    } else {
      // 不设有再来寻思自身实现
      //首先将盛传的参数以逗号隔绝,放到八个数组里面
      selectors = selector.split( ',' );
      // 循环遍历那些数组
    for ( i = 0; i < selectors.length; i++ ) {
      //在这里个轮回之中对数组里面包车型客车每叁个因素进行一个去除空格的操作,保障数据是我们想要的花样
      subselector = myTrim( selectors[ i ] );
      // 接下来便是 管理 subselector,使用正则举办剖断
    if ( rbaseselector.test( subselector ) ) {
      // 基本接受器
      //即便相配到了就将非常到的传播到中央的八种采纳器函数只中,再次来到三个数组,将以此数组举办八个push
    push.apply( results, basicSelect( subselector ) );
    } else {
      //如若匹配不到那么就选拔 select2 函数
      select2( subselector, results );
      }
    }
  }
    // 重返 result注意,这么些数组要拓展三个去重操作
    return unique( results );
  }
  //封装四个后裔接受器的函数,传入四个参数
  function select2 ( selector, results ) {
    results = results || [];
    //将那么些参数以逗号隔断
    var selectors = selector.split( ' ' );
    //声飞鹤个数组,那几个数组用于存放成分,以至叁个node数组,那么些数组用于寄存从哪叁个要素起首找
    var arr = [], node = [ document ];
    for ( var j = 0; j < selectors.length; j++ ) {
      for ( var i = 0; i < node.length; i++ ) {
      //因为那边查找的是儿孙采纳器,所以假若找到最终边的并将其归来就足以了
      push.apply( arr, basicSelect( selectors[ j ], node[ i ] ));
      }
    //在完工的时候将arr里面包车型大巴值全体给node,要小心那时node里面包车型地铁值的作用是怎么
    node = arr;
    //将arr清空
    arr = [];
    }
    //在最后将最终二次获得到的node值赋给results
    //这里面包车型大巴值是终极一回拿走到的因素,也正是说是要获得的后裔成分中的的末尾二个要素
    push.apply( results, node );
    return results;
    }
    return select;
  })();

本文由计算机操作发布,转载请注明来源:仿照jQuery写一个关于选择器的框架,带了注释