Jquery学习笔记 - 选择器


  Jquery选择器与CSS选择器非常相似,CSS选择器提供诸多功能,同时两者在解析上均采用从右向左解析,因为在建立Render Tree时,若采用自左向右解析,没词匹配不成功均需要退回再进行匹配,而反向解析利用排除法,逐步缩小元素候选集,优化了从子元素找父元素的过程,对于大量元素很有效(所以采用通配符很低效)

  CSS的基础选择器:

  群组选择器:selector1, selector2, selector3...

  简单选择器:ID" #id ",标签" tag ",类" .class ",属性“ [att , att=val , att~=val , att|=val ,att^=val ,att*=val ,att$=val] ”,通配符“ * ”

  关系选择器:孩子“parent > child”,后代“ancestor descendant”,相邻“prev + next”,兄弟“prev ~sibling”

  伪类选择器:动作伪类,目标伪类,语言伪类,状态伪类,结构伪类,取反伪类 (伪类采用筛选器,基本、内容、可见、子元素、表单筛选器)

  普通接口兼容性:

  关于属性attributes:IE8前必须使用getAttribute('className'),而其余为getAttribute('class')

  关于getElementById:IE8之前不区分ID大小写,且无法识别重名的表单name和ID

  关于getElementByTagName:IE6-8会将注释节点纳入通配符的选择范围,需要递归判断nidetype=1才可取

  关于getElementByClassName:IE不支持此方法

  

  //为通配符做兼容性处理

  function byTagName(tag, context) {

    var ele,

     tmp=[],

   index = 0,

      resulrs = context.getElementByTagName(tag);

    if(tag === "*") {

      while((ele = result[index++])) {

        if(ele.nodetype === 1) {

          tmp.push(ele);

        }  

      }

      return tmp;

    }

    return results;

  };

  //getElementsByClassName
  function getClassNames(tagName, classStr) {
    var nodes = document.getElementsByTagName(tagName),
    ret = [];
    for (i = 0; i < nodes.length; i++) {
      if (hasClass(nodes[i], classStr)) {
      ret.push(nodes[i])
      }
    }
    return ret;
  }

  function hasClass(tagStr, classStr) {
    var arr = tagStr.className.split(/\s+/);  //class可以有多个
    for (var i = 0; i < arr.length; i++) {
      if (arr[i] == classStr) {
      return true;
      }
    }
    return false;
  }

  高级接口querySelector:

  querySelector返回一个集合,element.querySelectorAll返回集合(nodelist)其中包括element本身,这两个选择器无论之前调用的上下文element如何,总是在document范围内查找所有满足的元素,其次查找上句中得到的元素集合中符合子元素,返回这些元素,于是自然包括element元素,这也解释了为何element元素会被返回

  高级接口兼容性:

  前文提到querySelectorAll无视上下文,始终在document中查找,这导致返回element本身,针对这个问题,采用Andrew Dupont方法加以修复 - 利用临时添加的ID显示范围,并在使用后删除,如下

  var context = document.querySelector('.aaron');
  var old;
  var nid = Math.random();

  //是否有ID/'|\\/g
  if ((old = context.getAttribute("id"))) {
    nid = old.replace(/'|\\/g, "\\$&");
  } else {
    context.setAttribute("id", nid);
  }
  nid = "[id='" + nid + "'] ";

  var newSelector = nid + '.aaron span';

  if (newSelector) {
    try {
      alert(context.querySelectorAll(newSelector).length)
    } catch (qsaError) {} finally {
    //如果是通过增加的范围,则要删除
      if (!old) {
        context.removeAttribute("id");
      }
    }
  }  

  源代码分析系列:

  init: function(selector, context, rootjquery) {

    //HANDLE: $(""), $(null), $(undefined), $(false)

      ...  若为null,undefined,false,直接 return this 返回原来的值

    //HANDLE HTML. string

    if(typeof selector === "string") {

      ...  特殊情况,下文详解

    //HANDLE $(DOMElement)

    } else if(selector.nodetype) {

      ...  若输入了dom元素,则直接返回由其构成的伪数组,this[0]=selector,this.length=1 即可

    //HANDLE $(function)

    } else if(jQuery.isFunction(selector)) {

      ...  等同于jQuery.ready(function),即 return rootjQuery.ready(selector)

    }

    //HANDLE $($...)

    if(selector.selector !== undefined) {

      ...  将参数执行结果包装到this上并返回

    }

    return jQuery.makeArray(selector, this);

  }

  若选择器是字符串,正则式匹配 test方法,match方法,exec方法;

  若为HTML字符串......;

  若为ID,调用JS原生方法并解决兼容问题;

参考 慕课网:https://www.imooc.com/learn/172

   博客园:https://www.cnblogs.com/chuaWeb/p/jQuery-1-9-1-jQuery-selector1.html

优质内容筛选与推荐>>
1、python学习(十一) 文件和流
2、Android的开发相对于tizen的开发难度
3、带参数的方法
4、Asp.Net MVC 实用视频教程
5、Table 内容自动换行


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号