skip to Main Content

how can I iterate through the divs inside one div, and if they all have the same ‘display’ value(‘none’), display a message?
I’m just learning and I need to use it one hundred percent
jQuery

<div class="test1">
 <div class="test2" style="display:none">
  
 </div>
 <div class="test2" style="display:none">
  
 </div>
 <div  class="test2" style="display:none">
  
 </div>
 <div  class="test2" style="display:none">
  
 </div>
</div>

I tried it using jQuery.each

  jQuery('.test1 > .test2').each(function(){
    if(jQuery(this).css('display') == 'none'){
        jQuery('.test_message').text('nothing');
    }
})

3

Answers


  1. The issue with your current logic is that you are testing each .test2 div individually, then outputting the message based on that single element. You instead need to check all the elements first, then output the message if necessary.

    To do that you can store a flag to determine the state of the divs, then change that flag if any one of them does not match that state. Here’s a working example:

    jQuery($ => {
      let allHidden = true;
    
      $('.test1 > .test2').each(function() {
        if ($(this).css('display') !== 'none') {
          allHidden = false;
          return;
        }
      })
    
      if (allHidden) {
        $('.test_message').text('nothing');
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <div class="test1">
      <div class="test2" style="display: none"></div>
      <div class="test2" style="display: none"></div>
      <div class="test2" style="display: none"></div>
      <div class="test2" style="display: none"></div>
    </div>
    
    <div class="test_message"></div>

    It would also be possible to do this without an explicit loop by using the :visible selector:

    jQuery($ => {
      if (!$('.test1 > .test2:visible').length) {
        $('.test_message').text('nothing');
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <div class="test1">
      <div class="test2" style="display: none"></div>
      <div class="test2" style="display: none"></div>
      <div class="test2" style="display: none"></div>
      <div class="test2" style="display: none"></div>
    </div>
    
    <div class="test_message"></div>

    Finally, note that in the examples above I used a shorthand document.ready handler, which aliases the $ variable. This means you are safe to use the $ prefix instead of the verbose jQuery keyword, without it affecting any other scripts which may also be using $.

    Login or Signup to reply.
  2. The easiest way is to change your logic. You can select all elements that have not the style="display:none" attribute and check the length of the Node List with !NodeList.length. If this statement is true, then all elements will have the attribute as nothing is returned:

    const visibleChildElements = document.querySelectorAll('.test1 > .test2:not([style*="display:none"])');
    
    if (!visibleChildElements.length) {
      console.log('all child elements are hidden');
    } else {
      console.clear();
    }
    <div class="test1">
      <div class="test2" style="display:none"></div>
      <div class="test2" style="display:none"></div>
      <div class="test2" style="display:none"></div>
      <div class="test2" style="display:none"></div>
    </div>

    As side-note: As said you should not focus on 100% jQuery in 2024. even Bootstrap-5 got rid of jQuery 2 years ago as it makes no longer sense. It is "outdated" as plain Javascript caught up with the functionality.

    If you want to select all child elements in JS you could also use querySelector('element').children

    Login or Signup to reply.
  3. Some of the other solutions will fail if the display value is set in external CSS

    Instead use checkVisibility

    Also note I use the more readable Array.from instead of the […collection] spread operator to get the array methods available on the collection

    const allHidden = Array.from(document.querySelectorAll('.test1 > .test2'))
      .every(el => !el.checkVisibility());
    
    document.getElementById('testMessage').textContent = allHidden ? 'all child elements are hidden' : 'some child elements are visible';
    .text3 { display: none; }
    <div class="test1">
      <div class="test2" style="display:none"></div>
      <div class="test2" style="display:none"></div>
      <div class="test2 text3"></div>
      <div class="test2" style="display:none"></div>
    </div>
    <span id="testMessage"></span>

    If you MUST use jQuery, then try

    const $test2Elements = $('.test1 > .test2')
    const allHidden = $test2Elements
      .map(function() { return $(this).is(":visible") }) // jQuery map
      .get() // get the array
      .every(e => !e); // look at each and return if true was found or run through all false
      
    $("#testMessage").text(allHidden ? 'all child elements are hidden' : 'some child elements are visible');
    .text3 { display: none; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    
    <div class="test1">
      <div class="test2" style="display:none"></div>
      <div class="test2" style="display:none"></div>
      <div class="test2 text3"></div>
      <div class="test2" style="display:none"></div>
    </div>
    <span id="testMessage"></span>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search