【问题标题】:jQuery find elements that match multiple conditionsjQuery查找匹配多个条件的元素
【发布时间】:2020-11-29 18:58:10
【问题描述】:

如果我有以下标记,我如何检查每个子项中的每个 div 是否没有隐藏类,以及它是否具有数据访问属性,其值等于 id=main 的 div 中的类的值

 <div id="main" class="agent">

   <div class="child">
     <div class="area hidden" >
        <div class="section">
           <div data-type="text" >
                 <input type="text" name="firstname">
             
           </div>
        </div>
      </div>
   </div>
   <div class="child">
     <div class="area" data-access="agent">
        <div class="section">
           <div data-type="text" >
                   <input type="text" name="lastname">
             
           </div>
        </div>
      </div>
   </div>
   <div class="child">
     <div class="area">
        <div class="section">
           <div data-type="text" >
                 <input type="text" name="refnumber">
           </div>
        </div>
      </div>
   </div>
   
   

我可以执行以下操作,但只检查 div 是否不包含隐藏类。

 $('.child').each(function(index, element) {

       $(element).find('.area:not(.hidden) .section:not(.hidden) div[data-type]:not(.hidden)').each(function(index, ele) {


       }

}

除了检查 div 是否不包含隐藏类之外,我还想检查每个 div 是否还包含数据访问属性,如果包含,则检查该值是否等于 @ 中的类的值987654323@

【问题讨论】:

  • 可以显着简化这一点,但不清楚更高级别的目标是什么。你需要对结果做什么?
  • @charlietfl 如果显示 div,则需要检索位于具有 data-type 属性的 div 内的表单输入值。如果它被隐藏了,那么它可以被忽略。容器的可见性可以在三个级别切换,即三个 div,因此需要检查它们是否被隐藏。

标签: javascript html jquery


【解决方案1】:

您可以首先检查是否有任何子元素具有隐藏的类 .not:has,然后检查是否有任何子元素的数据属性 data-access 等于 id 为 main 的元素类。

$('#main .child')
  .not(':has(.hidden)')
  .has(`[data-access="${$('#main').attr('class')}"]`)
  .css('color', 'red')
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="main" class="agent">
  <div class="child">
    <div class="area hidden">
      <div class="section">
        <div data-type="text">1 </div>
      </div>
    </div>
  </div>
  <div class="child">
    <div class="area" data-access="agent">
      <div class="section">
        <div data-type="text">2</div>
      </div>
    </div>
  </div>
  <div class="child">
    <div class="area">
      <div class="section">
        <div data-type="text">3 </div>
      </div>
    </div>
  </div>
</div>

【讨论】:

    【解决方案2】:

    使用 not()filter()hasClass() 的组合

    $('.child').not(':has(.hidden)')
          .find('[data-access]')
          .filter(function(){      
              return $('#main').hasClass($(this).data('access'))
          })
          .end()
          .find('[data-type="text"]')
          .text('Matches main').css('color','red')
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="main" class="agent">
    
       <div class="child">
         <div class="area hidden" >
            <div class="section">
               <div data-type="text" >Has hidden
               </div>
            </div>
          </div>
       </div>
       <div class="child">
         <div class="area" data-access="agent">
            <div class="section">
               <div data-type="text" >No hidden
               </div>
            </div>
          </div>
       </div>
       <div class="child">
         <div class="area">
            <div class="section">
               <div data-type="text" >No data access
               </div>
            </div>
          </div>
       </div>
       </div>

    【讨论】:

    • 如果 div 没有隐藏类,或者它们没有数据访问属性,或者如果它有数据访问属性并且它的值匹配 agent,那么它是可见的
    • 不清楚该评论的含义
    • @chalietfl 如果输入字段显示给用户我想检索值 - 请参阅更新的标记。然而,输入字段的可见性可以由三个父 div 控制。如果区域 div 具有隐藏类或数据访问属性,并且数据访问属性值与 div 中带有#main 的类的值不匹配(在本例中为它的代理),则输入字段被隐藏,因此可以忽略.我需要检查所有三个 div(区域、部分和数据类型 div 以查看输入字段是否可见。
    • 好的,那么使用我的过滤器方法有什么问题?也可以简化为$('.child input').filter(function(){ return !$(this).closest('.hidden').length})
    • 好吧,你没有检查输入字段的所有 3 个父 div 以查看它们是否还包含数据访问属性
    【解决方案3】:

    所以有什么想出来的希望它有所帮助

    $(document).ready(function(){
            let listOfDivs = $('.child').children().filter((index, el) => !el.getAttribute('hidden') && el.getAttribute('data-access'))
            // lets check the 0 index & compare it with the #main class name
            if($('#main')[0] && listOfDivs[0] && $('#main')[0].getAttribute('class') === listOfDivs[0].getAttribute('data-access')){
              console.log("Matched",listOfDivs[0])
            }
          });
    <!DOCTYPE html>
    <html lang="en">
    
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
      </head>
    
      <body>
        <div id="main" class="agent">
        </div>
        <div class="child">
          <div class="area hidden">
            <div class="section">
              <div data-type="text">
              </div>
            </div>
          </div>
        </div>
        <div class="child">
          <div class="area" data-access="agent">
            <div class="section">
              <div data-type="text">
              </div>
            </div>
          </div>
        </div>
        <div class="child">
          <div class="area">
            <div class="section">
              <div data-type="text">
              </div>
            </div>
          </div>
        </div>
    
        <script src="https://code.jquery.com/jquery-3.5.1.min.js"
          integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
      </body>
    </html>

    如果您想查看列表

    $(document).ready(function(){
            let listOfDivs = $('.child').children().filter((index, el) => !el.getAttribute('hidden') && el.getAttribute('data-access'))
            let main = $('#main').length ? $('#main')[0] : null
            
            if(main){
              let mainClassValue = main.getAttribute('class')
              for(let i = 0; i < listOfDivs.length; i++ ){
                if(mainClassValue === listOfDivs[i].getAttribute('data-access')){
                  console.log("Matched",listOfDivs[i])
                }
              }
            }
          });
    

    【讨论】:

    • OP 使用的是隐藏类,而不是属性,data-access 也可以存在于您孩子的孩子身上。当listOfDivs 的长度大于一时会发生什么?
    • 什么都不会,它只会检查第一个,但你想检查整个列表只需将 if 案例包装在一个循环中。
    【解决方案4】:

    根据您的第一个描述:

    <script>
    $(function () {
        function findDivs() {
            var $root = $('#main');
            var rootClass = $root.get(0).className;
    
            // each div inside each child does not have class hidden...
            return $('#main > .child > div:not(.hidden)').filter(function (idx, elem) {
                var access = elem.dataset.access;
    
                //  ...if it has a data-access attribute...
                if (access) {
                    // ..its value is equal to the value
                    // of the class in div with id=main
                    return access === rootClass;
                }
    
                // if it does not have data-access
                // attribute, return
                return true;
            });
        }
    
        // add this to an event handler
        console.log(findDivs());
    });
    </script>
    

    输出:

    0: <div class="area" data-access="agent">​
    1: <div class="area">
    

    如果您只想要带有[data-type] 的叶子div,您可以添加.find() 操作:

    <script>
    $(function () {
        function findDivs() {
            var $root = $('#main');
            var rootClass = $root.get(0).className;
    
            return $('#main > .child > div:not(.hidden)')
                .filter(function (idx, elem) {
                    var access = elem.dataset.access;
    
                    if (access) {
                        return access === rootClass;
                    }
    
                    return true;
                })
                .find('[data-type]'); // ADDED
        }
    
        console.log(findDivs());
    });
    </script>
    

    输出:

    0: <div data-type="text">​
    1: <div data-type="text">
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-22
      • 1970-01-01
      • 2020-02-25
      • 1970-01-01
      • 2015-05-13
      • 2020-02-23
      • 1970-01-01
      • 2012-11-19
      相关资源
      最近更新 更多