如果任何子元素具有某个类,则将类添加到父div,否则将其删除(jQuery或Javascript)

时间:2019-06-28 07:36:17

标签: javascript jquery

我有多个下拉菜单,每个下拉菜单都具有多个样式为复选框的按钮。单击其中一个按钮时,它将获得“活动”类。我想做的是,如果任何子元素(按钮)具有活动类(使用jQuery或Javascript),则将“活动”类添加到父下拉列表中。

HTML

<div class="dropdown dropdown-checkboxes">
    <div class="dropdown-toggle">Brand</div>
    <div class="dropdown-menu" data-filter-group="brand">
        <button class="control-condition custom-checkbox" data-toggle=".volvo"><span class="checkmark"></span>Volvo</button>
        <button class="control-condition custom-checkbox" data-toggle=".bmw"><span class="checkmark"></span>BMW</button>
        <button class="control-condition custom-checkbox" data-toggle=".fiat"><span class="checkmark"></span>Fiat</button>
        ...
    </div>
</div>

我尝试过的事情

$(".control-condition").click(function () {
    if ($('.dropdown-menu:has(.active)')) {
        $(this).parent().parent().addClass('active');
    }
    else {
        $(this).parent().parent().removeClass('active');
    }
});

这会像应有的那样将类“活动”添加到父级下拉列表中,但是当“未选中”按钮(没有活动的类)时,它不会删除该类。

任何建议或指导将不胜感激! :)

5 个答案:

答案 0 :(得分:0)

问题在于$('.dropdown-menu:has(.active)')将始终为true,您必须将支票更改为以下内容:

if ($('.dropdown-menu:has(.active)').length) { ... }

但是在这种情况下使用.toggleClass更合适,这是一个示例:

$(this).parent().parent().toggleClass('active', !!$('.dropdown-menu:has(.active)').length);

答案 1 :(得分:0)

您可以使用.hasClass()

$(".control-condition").click(function () {
    if (!$('.dropdown-menu').hasClass("active")) {
        $(this).parent().addClass('active');
    }
    else {
        $(this).parent().removeClass('active');
    }
});

但是请注意,您的逻辑有问题。您检查.dropdown-menu是否具有类active,但是由于该active而在dropdown-checkboxes上设置了$(this).parent().parent().addClass('active');

因此将$(this).parent().parent().addClass('active');更改为$(this).parent().addClass('active');
或将$('.dropdown-menu').hasClass("active")更改为$('.dropdown-checkboxes').hasClass("active")

演示

$(".control-condition").click(function () {
    if (!$('.dropdown-menu').hasClass("active")) {
        $(this).parent().addClass('active');
    }
    else {
        $(this).parent().removeClass('active');
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dropdown dropdown-checkboxes">
    <div class="dropdown-toggle">Brand</div>
    <div class="dropdown-menu" data-filter-group="brand">
        <button class="control-condition custom-checkbox" data-toggle=".volvo"><span class="checkmark"></span>Volvo</button>
        <button class="control-condition custom-checkbox" data-toggle=".bmw"><span class="checkmark"></span>BMW</button>
        <button class="control-condition custom-checkbox" data-toggle=".fiat"><span class="checkmark"></span>Fiat</button>
    </div>
</div>

答案 2 :(得分:0)

$('.dropdown').on('click', '.control-condition', function() {
  const parent = $(this).closest('.dropdown-menu');
  parent.toggleClass(
    'active',
    $('.control-condition.active', parent).is('.control-condition.active')
  );
})

如果要在active上使用.dropdown类,请将.dropdown-menu更改为.dropdown

这将跨浏览器在.dropdown-menu的所有当前和将来子级上运行(因为它绑定到下拉列表)。

如果您希望某些内容适用于当前版本,并且尚未在DOM中添加任何.dropdown,请将第一行更改为:

 $('body').on('click', '.dropdown .control-condition', function() {

有关事件委托的说明:将大量事件委托给'body'可能会并且将影响页面性能。请勿将事件频繁地委派给'body'事件,例如scrollmousemove。进一步了解event-performance

答案 3 :(得分:0)

您可以使用dropdown类迭代所有元素,如果它具有一些活动元素,则将其激活(首先从父级移除所有活动类,否则将被复制):

$(".control-condition").click(function () {
  $( "dropdown-menu" ).each(function( index ) {
     var element = $(this)
     // first we remove the class in case it already exist
     element.removeClass('active')
     // then we check if element with class active exist inside the menu
     if(element.find('.active').length == 1){
       element.addClass('active')
     }
  });
});

答案 4 :(得分:0)

我会使用香草Javascript,在99.99%的情况下。

const buttons = [...document.querySelectorAll('.dropdown-checkboxes .control-condition')];

document.querySelector('.dropdown-checkboxes')
  .addEventListener('click',
  ({target}) => {
    if (buttons.includes(target.closest('button'))) {
      target.closest('button').classList.toggle('active');
      target
        .closest('.dropdown') // get the parent you need
        .classList[buttons.some(btn => 
          btn.classList.contains('active')) // if any button has class active
          ? 'add' // add .active
          : 'remove' // otherwise remove .active
        ]
        ('active');
    }
  }
)
.checkmark::before {
  content: '✓';
  opacity: 0;
  transition: opacity .2s ease-out;
}

button.active>.checkmark::before {
  opacity: 1;
}

.dropdown {
  transition: background-color .3s ease-in-out;
}

.dropdown.active {
  background-color: lightgreen;
}
<div class="dropdown dropdown-checkboxes">
  <div class="dropdown-toggle">Brand</div>
  <div class="dropdown-menu" data-filter-group="brand">
    <button class="control-condition custom-checkbox" data-toggle=".volvo"><span class="checkmark"></span>Volvo</button>
    <button class="control-condition custom-checkbox" data-toggle=".bmw"><span class="checkmark"></span>BMW</button>
    <button class="control-condition custom-checkbox" data-toggle=".fiat"><span class="checkmark"></span>Fiat</button>
  </div>
</div>