搞清w3 selectors-api的工作方式

作者: nick 分类: 未分类 发布时间: 2010-04-07 15:39 ė 6没有评论

w3 2006 年就推出了w3 selectors-api 标准,目前支持的浏览器还不多.

今天在chrome和Firefox 3.1下做了一个测试,结果让我很迷惑

Html代码 复制代码
  • <html xmlns=”http://www.w3.org/1999/xhtml”>  
  •   <head>  
  •     <title>Selectors API Example</title>  
  •   </head>  
  •   <body>  
  •     <span>body span1</span>  
  •     <span>body span2</span>  
  •     <div id=’bar’>  
  •       <span>span1</span>  
  •       <div>  
  •           <span>span2</span>  
  •       </div>  
  •     </div>  
  •   </body>  
  • </html>  
  • <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <title>Selectors API Example</title>
      </head>
      <body>
        <span>body span1</span>
        <span>body span2</span>
        <div id='bar'>
          <span>span1</span>
          <div>
              <span>span2</span>
          </div>
        </div>
      </body>
    </html>

     

    Js代码 复制代码
  • alert(document.getElementById(‘bar’).querySelectorAll(‘div span’).length);//2  
  • alert(document.getElementById('bar').querySelectorAll('div span').length);//2

     而目前常用的javascript框架中的选择器使用:jQuery举例

    Js代码 复制代码
  • alert($(‘div span’,’#bar’).length);//1  
  • alert($('div span','#bar').length);//1

    很明显w3的标准在匹配选择符的时候首先把查询范围的Element也包括进去了,而目前的框架是在查询范围的Element的子节点查找的.可是这样的话如果按w3的标准想要剔除这个范围的Element的话,上面的例子就要写成

    Js代码 复制代码
  • alert(document.getElementById(‘bar’).querySelectorAll(‘div div span’).length);//1  
  • alert(document.getElementById('bar').querySelectorAll('div div span').length);//1

    也许还有其他的写法.

    如果只想选择span1的话

    Js代码 复制代码
  • //第一种情况,范围没有确定,也就是一个selector表达式下   
  • document.querySelectorAll(‘#bar>span’).length;//1   
  • $(‘#bar>span’).length;//1   
  • //第二种情况,范围已经确定,   
  • $(‘>span’,’#bar’).length;//1   
  • document.querySelectorAll(‘span’,document.querySelector(‘#bar’).length;//2   
  • document.querySelectorAll(‘>span’,document.querySelector(‘#bar’).length;//出错了,不能这样写  
  • //第一种情况,范围没有确定,也就是一个selector表达式下
    document.querySelectorAll('#bar>span').length;//1
    $('#bar>span').length;//1
    //第二种情况,范围已经确定,
    $('>span','#bar').length;//1
    document.querySelectorAll('span',document.querySelector('#bar').length;//2
    document.querySelectorAll('>span',document.querySelector('#bar').length;//出错了,不能这样写

    我不知道是否是chrome 和Firefox 3.1 的实现有问题.还是他们都太按标准来了.

    从某种程度上讲,w3把查询范围的Element也包括进去不是什么大问题,毕竟这是标准,大家习惯了就行了,可是

    不支持 ‘>span’

    这种写法就有问题了.如果其他的浏览器在实现上也这样做的话,那么这个标准就形同虚设了.

    更进一步的测试:

    Js代码 复制代码
  • document.getElementById(‘bar’).querySelectorAll(‘*’).length;//3,这次不包括查询范围了.   
  • document.getElementById(‘bar’).querySelectorAll(‘* div span’).length;//2,又包括了   
  • document.getElementById(‘bar’).querySelectorAll(‘#bar’).length;//0,又不包括了  
  • document.getElementById('bar').querySelectorAll('*').length;//3,这次不包括查询范围了.
    document.getElementById('bar').querySelectorAll('* div span').length;//2,又包括了
    document.getElementById('bar').querySelectorAll('#bar').length;//0,又不包括了

    事情更复杂了,选择器可以很复杂,但是对于范围的确定不应该有二义性.
    ======PS======
    经过思考和hax的回复,终于搞清楚了,w3 设计的这个selectors-api是个
    纯支持CSS selectors
    同时标题也应该改改了
    他要达到的是和在样式表里面写的css选择到的 elements 完全一致的结果。
    而我们在写程序的时候和这个情形不一样,因为写css的时候是一次完成的,初始范围是整个document的所有节点.
    写程序的时候,是有中间过程的,一次选择后的结果会被再一次做为初始范围。这和上面的就不同了。
    用hax的描述说就是

    写道
    但现在浏览器中的CSS是没有局部化的selector 概念的,所以不支持也是情有可原

    这样看来,还是要依靠像jQuery 这样的选择器一阵子了
    ===来自hax的测试代码===

    Js代码 复制代码
  • document.querySelectorAll(‘span’).length;//4   
  • bar.querySelectorAll(‘span’).length;//2   
  • document.querySelectorAll(‘body span’).length;//4   
  • bar.querySelectorAll(‘body span’).length;//仍然是2而   
  • $(‘body span’, bar);//则返回 null  
  • document.querySelectorAll('span').length;//4
    bar.querySelectorAll('span').length;//2
    document.querySelectorAll('body span').length;//4
    bar.querySelectorAll('body span').length;//仍然是2而
    $('body span', bar);//则返回 null

    所以 bar.querySelectorAll(‘body span’) 的意思是
    符合 body span 并且属于 bar 的子树的节点。
    而 $(‘body span’, bar) 表示的是
    以bar为context,匹配 body span ,也就是相当于:
    document.querySelectorAll(‘#bar body span’)

    本文出自 传播、沟通、分享,转载时请注明出处及相应链接。

    本文永久链接: https://www.nickdd.cn/?p=22

    发表评论

    您的电子邮箱地址不会被公开。

    Ɣ回顶部