为什么我的jQuery:not()选择器不工作在CSS? [英] Why is my jQuery :not() selector not working in CSS?

查看:93
本文介绍了为什么我的jQuery:not()选择器不工作在CSS?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这种布局:

 < div id =sectors> 
< h1> Sectors< / h1>
< div id =s7-1103class =alpha>< / div>
< div id =s8-1104class =alpha>< / div>
< div id =s1-7605class =beta>< / div>
< div id =s0-7479>< / div>
< div id =s2-6528class =gamma>< / div>
< div id =s0-4444>< / div>
< / div>

使用这些CSS规则:

  #sectors {
width:584px;
background-color:#ffd;
margin:1.5em;
border:4px dotted#000;
padding:16px;
overflow:auto;
}

#sectors> h1 {
font-size:2em;
font-weight:bold;
text-align:center;
}

#sectors> div {
float:left;
position:relative;
width:180px;
height:240px;
margin:16px 0 0 16px;
border-style:solid;
border-width:2px;
}

#sectors> div :: after {
display:block;
position:absolute;
width:100%;
bottom:0;
font-weight:bold;
text-align:center;
text-transform:capitalize;
background-color:rgba(255,255,255,0.8);
border-top:2px solid;
content:attr(id)' - 'attr(class);
}

#sectors> div:nth-​​of-type(3n + 1){
margin-left:0;
}

#sectors> div.alpha {color:#b00; background-color:#ffe0d9; }
#sectors> div.beta {color:#05b; background-color:#c0edff; }
#sectors> div.gamma {color:#362; background-color:#d4f6c3; }



我使用jQuery添加 unassigned 类别到没有其他类别 alpha beta gamma

  $('#sectors> div:not .alpha,.beta,.gamma)')。addClass('unassigned'); 

然后我对该类应用一些不同的规则:

  #sectors> div.unassigned {
color:#808080;
background-color:#e9e9e9;
opacity:0.5;
}

#sectors> div.unassigned :: after {
content:attr(id)' - Unassigned';
}

#sectors> div.unassigned:hover {
opacity:1.0;
}

并且一切在现代浏览器中完美无缺。



互动式jsFiddle预览



但看到 :not()选择器jQuery 基于 :not()在CSS3 ,我想我可以把它直接到我的样式表,所以我不必依靠添加一个额外的类使用jQuery。此外,我对于支持旧版本的IE不感兴趣,其他浏览器对:not()选择器有很好的支持。



所以我尝试改变上面的 .unassigned 部分到这里(知道我将只有我的布局中的部门Α,Β和Γ) p>

  #sectors> div:not(.alpha,.beta,.gamma){
color:#808080;
background-color:#e9e9e9;
opacity:0.5;
}

#sectors> div:not(.alpha,.beta,.gamma):: after {
content:attr(id)' - Unassigned';
}

#sectors> div:not(.alpha,.beta,.gamma):hover {
opacity:1.0;
}

但是一旦我这样做,它就会停止工作浏览器!



更新,但不是如此交互jsFiddle预览



为什么:not() selector在jQuery中工作,但在CSS中失败?不应该在两个地方工作相同,因为jQuery声称是CSS3兼容,或有一些我缺少的?



有一个纯CSS解决方法

解决方案


为什么:not() selector在jQuery中工作但在CSS中失败?不应该在两个地方工作相同,因为jQuery声称是CSS3兼容,还是有一些我缺少的?


可能应该,但事实证明,它不:jQuery扩展:not()选择器以便可以将任何选择器传递给,无论其复杂程度如何它可能是,我怀疑的主要原因是为了与 .not()方法,其也相应地接受任何任意复杂的选择器和过滤器。



另一个例子,这个工作很好(我知道这是一个

 这是一个非常可笑的例子, / * 
*选择任何部分
*,它既不是具有类
*的body的子体,也不是具有类的后代的body的子体。
* /
$('section:not(body> [class],body>:has([class]))')
pre>

jsFiddle预览



请记住,将逗号分隔的选择器列表传递给:not()表示过滤那些不匹配任何

现在 :not()伪类本身是非常有限的。您只能将一个简单选择器作为参数传递给:not()。这意味着您一次只能传递以下任何一项:




  • 通用选择器( * ),可选择使用命名空间

  • 类型选择器( a div span ul li 等),可选择使用

  • 属性选择器( [att] [att = val] 等),可选择使用命名空间

  • 类选择器( .class

  • 选择器( #id

  • 伪类(:pseudo-class rel =noreferrer> jQuery的:not()选择器和当前标准的:not()选择器


    1. 首先,直接回答问题:您不能传递逗号分隔的选择器列表。 > 1 例如,虽然给定的选择器在jQuery中工作,但在小提琴中显示,它是无效的CSS:

        / *如果它不在Α,Β或Γ扇区,则它是未分配的* / 
      #sectors> div:not(.alpha,.beta,.gamma)




      有一个纯CSS解决方法为这个或者我将依靠一个脚本?


      谢谢,在这种情况下,有。你只需要连接多个:not()选择器,以使其有效CSS:



      < pre class =lang-css prettyprint-override> #sectors> div:not(.alpha):not(.beta):not(.gamma)

不会使选择器更长时间,但是不一致和不便仍然显而易见。



更新了互动式jsFiddle预览


  • 用于:not()这在jQuery中有效,但是无效的CSS:



    / *不要找到有所有三个类一起的div * /
    #foo> div:not(.foo.bar.baz)

    您需要将其拆分为多个否定(不只是链接他们!)使它有效CSS:

      #foo& div:not(.foo),#foo> div:not(.bar),#foo> div:not(.baz)

    正如你所看到的,这比第1点更不方便。

  • b $ b

      / * 
    *抓取既不是#foo本身也不在#foo内的一切。
    *注意#foo和*之间的后代组合器(空间)。
    * /
    :not(#foo,#foo *)

    是一个特别讨厌的情况,主要是因为它没有适当的解决方法。有一些松散解决方法( 1 2 ),但它们几乎总是依赖于HTML结构,因此在实用性上非常有限。


  • 使用:not()实现 querySelectorAll():not() 在一个选择器字符串中,使它成为一个有效的CSS选择器将导致该方法直接返回结果,而不是回退到Sizzle(jQuery的选择器引擎,实现: not()扩展)。


  • 这是一个非常小的奖金,好消息是,选择器4增强了:not() selector 以允许以逗号分隔的复杂选择器列表。复合选择器简单地是单个简单或复合选择器,或者是由组合器分离的整个复合选择器链。简而言之,您在上面看到的一切。



    这意味着上面的jQuery示例将成为有效的4级选择器,这将使伪类更有用CSS实现在未来几年开始支持它。






    1 href =http://kilianvalkhof.com/2008/css-xhtml/the-css3-not-selector =noreferrer>本文说,您可以将以逗号分隔的选择器列表传递给:not()在Firefox 3中,你不应该能够。如果它在Firefox 3中工作,因为该文章声称,那是因为Firefox 3中的一个错误,我找不到票了,但它不应该工作,直到未来的浏览器实现未来的标准。看到这篇文章到目前为止被引用的频率,我留下了评论这个效果,但看到文章多久,网站不常更新,我真的不指望作者回来修复它。


    I have this layout:

    <div id="sectors">
        <h1>Sectors</h1>
        <div id="s7-1103" class="alpha"></div>
        <div id="s8-1104" class="alpha"></div>
        <div id="s1-7605" class="beta"></div>
        <div id="s0-7479"></div>
        <div id="s2-6528" class="gamma"></div>
        <div id="s0-4444"></div>
    </div>
    

    With these CSS rules:

    #sectors {
        width: 584px;
        background-color: #ffd;
        margin: 1.5em;
        border: 4px dashed #000;
        padding: 16px;
        overflow: auto;
    }
    
    #sectors > h1 {
        font-size: 2em;
        font-weight: bold;
        text-align: center;
    }
    
    #sectors > div {
        float: left;
        position: relative;
        width: 180px;
        height: 240px;
        margin: 16px 0 0 16px;
        border-style: solid;
        border-width: 2px;
    }
    
    #sectors > div::after {
        display: block;
        position: absolute;
        width: 100%;
        bottom: 0;
        font-weight: bold;
        text-align: center;
        text-transform: capitalize;
        background-color: rgba(255, 255, 255, 0.8);
        border-top: 2px solid;
        content: attr(id) ' - ' attr(class);
    }
    
    #sectors > div:nth-of-type(3n+1) {
        margin-left: 0;
    }
    
    #sectors > div.alpha { color: #b00; background-color: #ffe0d9; }
    #sectors > div.beta  { color: #05b; background-color: #c0edff; }
    #sectors > div.gamma { color: #362; background-color: #d4f6c3; }
    

    I use jQuery to add the unassigned class to sectors that don't otherwise have one of the classes alpha, beta or gamma:

    $('#sectors > div:not(.alpha, .beta, .gamma)').addClass('unassigned');
    

    Then I apply some different rules to that class:

    #sectors > div.unassigned {
        color: #808080;
        background-color: #e9e9e9;
        opacity: 0.5;
    }
    
    #sectors > div.unassigned::after {
        content: attr(id) ' - Unassigned';
    }
    
    #sectors > div.unassigned:hover {
        opacity: 1.0;
    }
    

    And everything works flawlessly in modern browsers.

    Interactive jsFiddle preview

    But seeing as the :not() selector in jQuery is based on :not() in CSS3, I was thinking I could move it directly into my stylesheet so I wouldn't have to rely on adding an extra class using jQuery. Besides, I'm not really interested in supporting older versions of IE, and other browsers have excellent support for the :not() selector.

    So I try changing the .unassigned portion above to this (knowing I will only have sectors Α, Β and Γ in my layout):

    #sectors > div:not(.alpha, .beta, .gamma) {
        color: #808080;
        background-color: #e9e9e9;
        opacity: 0.5;
    }
    
    #sectors > div:not(.alpha, .beta, .gamma)::after {
        content: attr(id) ' - Unassigned';
    }
    
    #sectors > div:not(.alpha, .beta, .gamma):hover {
        opacity: 1.0;
    }
    

    But as soon as I do this it stops working — in all browsers! My unassigned sectors aren't grayed out, faded out or labeled 'Unassigned' anymore.

    Updated but not so interactive jsFiddle preview

    Why does the :not() selector work in jQuery but fail in CSS? Shouldn't it work identically in both places since jQuery claims to be "CSS3 Compliant", or is there something I'm missing?

    Is there a pure CSS workaround for this or will I have to rely on a script?

    解决方案

    Why does the :not() selector work in jQuery but fail in CSS? Shouldn't it work identically in both places since jQuery claims to be "CSS3 Compliant", or is there something I'm missing?

    Perhaps it should, but it turns out that it doesn't: jQuery extends the :not() selector such that you can pass any selector to it, no matter how complex it may be, and I suspect that the main reason for this is for parity with the .not() method, which also takes any arbitrarily complex selector and filters accordingly. It does in a way maintain a CSS-like syntax, but it extends from what's defined in the standard.

    As another example, this works just fine (I know it's an incredibly ludicrous example compared to what's given in the question, but it's just for illustrative purposes):

    /* 
     * Select any section
     * that's neither a child of body with a class
     * nor a child of body having a descendant with a class.
     */
    $('section:not(body > [class], body > :has([class]))')
    

    jsFiddle preview

    Remember that passing a comma-separated list of selectors to :not() means filtering elements that don't match any of the listed selectors.

    Now the :not() pseudo-class in Selectors level 3, on the other hand, is very limited by itself. You can only pass a single simple selector as an argument to :not(). This means you can pass only any one of these at a time:

    • Universal selector (*), optionally with a namespace
    • Type selector (a, div, span, ul, li, etc), optionally with a namespace
    • Attribute selector ([att], [att=val], etc), optionally with a namespace
    • Class selector (.class)
    • ID selector (#id)
    • Pseudo-class (:pseudo-class)

    So, here are the differences between jQuery's :not() selector and the current standard's :not() selector:

    1. First and foremost, to answer the question directly: you can't pass a comma-separated selector list.1 For example, while the given selector works in jQuery as demonstrated in the fiddle, it isn't valid CSS:

      /* If it's not in the Α, Β or Γ sectors, it's unassigned */
      #sectors > div:not(.alpha, .beta, .gamma)
      

      Is there a pure CSS workaround for this or will I have to rely on a script?

      Thankfully, in this case, there is. You simply have to chain multiple :not() selectors, one after another, in order to make it valid CSS:

      #sectors > div:not(.alpha):not(.beta):not(.gamma)
      

      It doesn't make the selector that much longer, but the inconsistency and inconvenience remain evident.

      Updated interactive jsFiddle preview

    2. You can't combine simple selectors into compound selectors for use with :not(). This works in jQuery, but is invalid CSS:

      /* Do not find divs that have all three classes together */
      #foo > div:not(.foo.bar.baz)
      

      You'll need to split it up into multiple negations (not just chain them!) to make it valid CSS:

      #foo > div:not(.foo), #foo > div:not(.bar), #foo > div:not(.baz)
      

      As you can see, this is even more inconvenient than point 1.

    3. You can't use combinators. This works in jQuery, but not CSS:

      /* 
       * Grab everything that is neither #foo itself nor within #foo.
       * Notice the descendant combinator (the space) between #foo and *.
       */
      :not(#foo, #foo *)
      

      This is a particularly nasty case, primarily because it has no proper workaround. There are some loose workarounds (1 and 2), but they almost always depend on the HTML structure and are therefore very limited in utility.

    4. In a browser that implements querySelectorAll() and the :not() selector, using :not() in a selector string in a way that makes it a valid CSS selector will cause the method to return results directly, instead of falling back to Sizzle (jQuery's selector engine which implements the :not() extension). If you're a stickler for performance, this is a positively minuscule bonus you'll definitely salivate over.

    The good news is that Selectors 4 enhances the :not() selector to allow a comma-separated list of complex selectors. A complex selector is simply either a lone simple or compound selector, or an entire chain of compound selectors separated by combinators. In short, everything you see above.

    This means that the jQuery examples above will become valid level 4 selectors, which will make the pseudo-class much, much more useful when CSS implementations begin supporting it in the coming years.


    1 Although this article says that you can pass a comma-separated list of selectors to :not() in Firefox 3, you're not supposed to be able to. If it works in Firefox 3 as that article claims, then it's because a bug in Firefox 3 for which I can't find the ticket anymore, but it shouldn't work until future browsers implement future standards. Seeing how often that article is cited to date, I've left a comment to this effect, but seeing also how old the article is and how infrequently the site is being updated, I'm really not counting on the author coming back to fix it.

    这篇关于为什么我的jQuery:not()选择器不工作在CSS?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆