• QWrap Selector解密之一:认识selector写法


    QWrap使用了一个独立的QW.Selector,而不是借用sizzle。
    相对于sizzle,QW.Selector摈弃了isXml参数(无情抛弃)与selector群组除重排序(实用意义有限而效率影响太大);提供query方法之外,还提供了filter等与selector有关的其它一些方法,(详见:QW Selector简介);比sizzle更严谨的对待需要回溯的selector(详见:jquery delegate美中不足);体积小于sizzle的70%;性能也相当。两年来虽说没啥大变化,现在看来也不见得比当今的sizzle逊色,所以QWrap在开源时,也决定继续使用它。
    业界关心Selector实现的同学很少,自己实现过Selector的人数就更不用说,可还是有同学建议我写一些关于selector实现的文章。
    尽管也不会有几个读者有兴趣,但是,从思维沉淀出文章,对自己本人来说,也是一件挺有意义的事,所以,还是费点心思写一写吧。

    先来认识一下这个选择器甲:“textarea,#myId>input.date[type=text]:enabled”
    其中的“,”是并联关系符,它把选择器甲拆成选择器甲A“textarea”甲B“#myId>input.date[type=text]:enabled”两个选择器。
    并联的意思是:如是一个元素符合甲A或甲B,那么这个元素满足甲。

    含有并联关系符“,”的选择器,叫选择器群组。它也是广义的选择器。
    而选择器甲A与甲B,是独立选择器

    认识一下选择器甲B:“#myId>input.date[type=text]:enabled”
    其中的“>”是亲子关系符,它把甲B拆分成选择器甲B1“#myId”甲B2“input.date[type=text]:enabled”两个选择器。
    css3一共有五个关系符(combinator):
    “,” 并联关系符(优先级最高),“div,span”表示div或span
    “ ” 后代关系符,“div span”表示div的span后代
    “>” 亲子关系符,“div>span”表示div的span儿子
    “+” 相邻兄弟关系符,“div+span”表示div的相邻的span弟弟
    “~” 兄弟关系符,“A~B”表示div的span弟弟
    这里,把不含关系符的选择器叫自选器,例如甲A“textarea”、甲B1“#myId”、甲B2“input.date[type=text]:enabled

    认识一下自选器甲B2“input.date[type=text]:enabled”
    表示“tagName是INPUT”并且“className含有date”并且“[type=text]”并且“:enable”
    它们可以分成三类:
    写法快捷选择器:包括*、tagName、#id、.className四种
    属性选择器:被方括号括起
    伪类选择器:以冒号加伪类名表示,对于支持参数的伪类,用括号括起参数,例如“:nth-child(odd)”

    通常,理解这么多,我们写css就差不多够了。
    但是,很多同学对选择符有一个误解,这误解导致我们在解密选择器的实现时,先就有了一个结。
    问题1:选择器甲B“#myId>input.date[type=text]:enabled”里面有几个自选器,有几个关系符?
    ----很自然的回答是:两个自选器,一个关系符。
    问题2:选择器“#myId div>input.date[type=text]:enabled”里面有几个自选器,有几个关系符?
    ----很自然的回答是:三个自选器,两个关系符。
    问题3:为什么自选器要比关系符多一个?
    ----为什么呢!!那我们再重新来认识一下独立选择器。

    先看一下querySelectorAll方法标准
    The querySelectorAll() method on the NodeSelector interface must, when invoked,
    return a NodeList containing all of the matching Element nodes within the node’s subtrees, in document order. If there are no such nodes, the method must return an empty NodeList.
    意译为:返回匹配selector的子节点集合。
    但是它没有说明,这个selector的参考起点。
    例如,对于这样的树结构:html>body>div#div1>div#div2
    document.getElementById('div1').querySelectorAll('div');//这个很清晰,返回的是:[div#div2]
    document.getElementById('div1').querySelectorAll('div div');//这个呢?返回的是:[div#div2],还是空集合[]?
    事实上,浏览器原生的,返回的都是[div#div2];而jquery的$('#div1').find('div div'),返回的是空集合(低于1.6的jquery存在使用原生querySelectorAll不一致的问题)。
    也就是说,它实现的情况是标准里的这种用法的结果一致:
    document.getElementById('div1').querySelectorAll(':scope div div'); (注:scope伪类参见:http://dev.w3.org/2006/webapi/selectors-api2/#the-scope-pseudo-class
    也就是说,jquery在传入的selector参数前默认加上了:scope
    所以,jquery也可以这么用:
    $('#div1').css('color','red').find('>div').css('color','blue');
    QWrap的策略与jquery的一致,QW中对应的用法是:
    W('#div1').css('color','red').query('>div').css('color','blue');
    第二个selector是“>div”,它有一个自选器,有一个关系符,即:自选器数并不比关系符数多。

    现在,我们重新来回答这个问题:选择器甲B“#myId>input.date[type=text]:enabled”里面有几个自选器,有几个关系符?
    ----我会回答,在#myId前,其实还应该有一个“ ”后代关系符,不过,我们把它省略掉了。也就是:它有两个自选器,两个关系符,不过,书写时省掉了开头的那个后代关系符。

    附:QWrap网址:http://www.qwrap.com
  • 相关阅读:
    搭建JUnit环境
    搭建日志环境并配置显示DDL语句
    先建表还是先建实体类
    hbm2ddl
    总结与提纲
    常见O/R框架介绍
    hibernate 模拟实现和What is and Why O/R Mapping
    hibernate 注解不给提示
    额,你在main.xml中加了一个id以后,要右键点save,才会将这个id加入到R中,否则是没有的。。。R里的东西是程序自动生成的~~~
    导入android工程@Override报错
  • 原文地址:https://www.cnblogs.com/jkisjk/p/qwrap_selector_knowit.html
Copyright © 2020-2023  润新知