【问题标题】:Concatenate CSS selectors连接 CSS 选择器
【发布时间】:2015-04-16 20:22:56
【问题描述】:

有没有更聪明的方法可以让我使用$self 而不是在$('.foo.bar') 中使用foo...?感觉额外的 foo 是多余的。我不想浏览我已经找到的一些选择器。

$('.foo').on('click', function () {
    $self = $(this);
    $('.foo.bar').removeClass('bar'); // Works but feels wrong.
    //$self('bar').removeClass('bar'); // Use something that doesn't uses 'foo' again..
});

编辑

标记代码:

<div class="foo bar">
</div>

注意$('.foo.bar')foobar 之间没有空格。

【问题讨论】:

  • 你到底想做什么?您想仅从单击的元素中删除 css .bar 类还是从所有 .foo 元素中删除?
  • 我认为你的选择器是正确的
  • 嗯无法让任何建议起作用,我大多数地方都有错误。我会尝试更多
  • @radbyx:如果您在让任何建议发挥作用时遇到问题,您能否发布一个 jsFiddle/jsBin 来展示您拥有的东西?
  • 是的,我会在尝试您的答案后制作一个小提琴。最后一个我没有。

标签: jquery css jquery-selectors css-selectors


【解决方案1】:

所有当前答案都假定点击的.foo 将是唯一 .foobar 类。

...如果总是这样,那就太好了,但请注意,这些答案不是直接替代您所拥有的(因为您寻找 all em> .foo 的班级 bar)。以下是一个更多直接替换:

var foos = $('.foo').on('click', function () {
    $self = $(this);

    foos.filter('.bar').removeClass('bar');
});

...但请注意,此代码仍然 不是直接替换,因为您的代码将在 DOM 中获得 .foo在触发点击事件时,而我建议的替代方案将在点击事件被绑定时获得.foo


此外,在删除该类之前检查一个 jQuery 元素是否有一个类,有点多余;因为如果你告诉它从元素中删除一个不存在的类,jQuery 就不会出错;它不会做任何事情。

if (self.hasClass('bar')) {
    self.removeClass('bar');
}

...相反,只需这样做:

self.removeClass('bar');

【讨论】:

  • 在外面保存 foos 对我有用。那么 foos 的寿命是多少呢?我是否必须担心它会污染全局命名空间或窗口对象?我没有动态添加任何 foo。
  • @radbyx:生命周期将与捕获foos 变量的任何闭包一样长(换句话说,任何可以访问foos 的函数的生命周期)。在简单的情况下,您已将代码缩减为,这将是您的.foo 上的点击处理程序的生命周期。我假设代码在 $(document).ready() 块内,在这种情况下 foos 是在该块本地定义的,而不是在全局范围内。如果您想进一步缩小范围,可以使用 IIFE,a'la jsfiddle.net/oq7fu1hs
  • 感谢您的信息。顺便说一句,您的解决方案工作正常且有意义,但我有最后一个问题。这仍然感觉像是一种权衡,而不仅仅是一场胜利。您的解决方案重用了您已经找到的内容,但引入了一个变量。我猜我的速度较慢,但​​没有新变量。你会用什么?我知道最后它可能甚至不引人注意,因为它实际上是一个静态菜单,几乎没有项目。 :)
  • @radbyx:就其价值而言,JavaScript 中的变量真的很便宜,所以你几乎永远不会失去使用它们的机会。从更一般的意义上说,一个领域的性能提升通常是以其他地方的性能下降为代价的;在您的原始代码中,虽然您没有定义 foos 变量的(诚然很小,但仍然存在)“设置”成本,但您确实遭受了每次点击时必须重新查找 .foo.bar 的成本处理程序被调用。在我的代码中,您有初始设置时间,但在点击处理程序中有所收获。
  • ...在这些情况下,我尝试针对“常见情况”进行优化;你会产生一次设置成本,但点击处理程序可能会被触发多次,所以在我看来优化点击处理程序是有意义的。正因为如此,我会选择使用foos 变量的方法;但同样,这无疑是为了微小性能提升。
【解决方案2】:

方法一 hasClass()

$self.hasClass("bar") && $self.removeClass('bar');

方法二 is()

$seld.is(".bar")  && $self.removeClass('bar');

方法3 filter()

$seld.filter(".bar").removeClass('bar');

【讨论】:

  • 方法 1 和 2 不起作用,因为 ishasClass 返回布尔值,而不是 jQuery 对象。此外,filter 会找到所有具有 bar 类的子元素,而不仅仅是被点击的元素。
【解决方案3】:

您可以使用ishasClass 来检查当前元素是否也有bar 类:

$('.foo').on('click', function () {
    $self = $(this);
    $self.is('.bar') && $self.removeClass('bar');
});

【讨论】:

    【解决方案4】:

    使用这个简单的逻辑:If X has a class Y, remove class Y from X.

    代码如下:

    $('.foo').on('click', function () {
    
        $self = $(this);
    
        if($self.hasClass('bar'))
            $self.removeClass('bar');
    
    });
    

    阅读:

    【讨论】:

      【解决方案5】:

      如果你为每个父元素使用 id,你可以使用类似的东西:

      $('.foo').on('click', function () {
         $('#'+this.id).removeClass('bar'); // it will remove child class bar
      )};
      

      【讨论】:

        猜你喜欢
        • 2016-07-24
        • 2018-06-22
        • 1970-01-01
        • 1970-01-01
        • 2012-12-31
        • 2013-11-27
        • 2014-10-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多