Как использовать вложенные фильтры, чтобы определить, существует ли только один li и что его дочерний элемент равен <strong> - PullRequest
1 голос
/ 23 октября 2019

Мне нужно применить класс к <ul>, только если у него есть единственный <li>, который содержит только одного дочернего элемента, который должен быть <strong> и ничего больше (без текстового узла или других элементов до или после * 1004). *.

Я ссылался здесь на несколько сообщений, которые решают различные части проблемы выше, и я написал следующий код. Однако он добавляет класс ко всем <ul>, а условие фильтрации неполучать заявку.

$('ul.list-style').filter(function(){   
                return $(this).children("li")
                              .filter(function(){ return $(this).contents()
                                          .filter(function() { return this.nodeType == Node.ELEMENT_NODE || (this.nodeType == Node.TEXT_NODE && !!$.trim(this.nodeValue)) }).length=1 })
                              .filter(function(){ return $(this).children("strong").length = 1 }).length = 1 })
                .addClass("only-strong");

Ответы [ 3 ]

2 голосов
/ 23 октября 2019

Альтернатива - один фильтр - я считаю, что это работает

$('ul.list-style > li:only-child > strong:only-child').filter(function() {
  return !this.nextSibling;
}).parent().parent('ul.list-style').addClass('only-strong');
.only-strong {
  color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class='list-style'>
  <li><strong>Must be RED</strong></li>
</ul>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class='list-style'>
  <li>Also must be <strong>RED</strong></li>
</ul>
<ul class='list-style'>
  <li>Can't be <strong>Red</strong> with text outside of strong</li>
</ul>
<ul class='list-style'>
  <li><strong>Should not be red</strong></li>
  <li>has two li's</li>
</ul>
<ul class='list-style'>
  <li><strong>Not red</strong> something after strong</li>
  <li><strong>and has two li's</strong></li>
</ul>
<ul class='list-style'>
  <li><strong>NOT RED </strong><span>there's a span here</span></li>
</ul>

примечание о

return !this.nextSibling;

Это означает, что strong - последний узел в li, но вы можете иметьтекстовые узлы перед ним ... если это должен быть ONLY узел в li

return !(this.nextSibling || this.previousSibling);

или даже

return this.nextSibling === this.previousSibling;

, поскольку это только когда-либо верноесли оба null

1 голос
/ 23 октября 2019

Вы можете использовать приведенный ниже код в качестве альтернативы своему коду -

$('ul.list-style').filter(function() {
    if($(this).children('li').length ==1) {
       var hasStrongElementOnly = false;
       var $children = $(this).children('li').children();
       if($children.length > 0 ) {
         hasStrongElementOnly = true;
       }
       $(this).children('li').children().each(function(){
           if(!$(this).is('strong')) {
              hasStrongElementOnly = false;
           }
       });
       
       if(hasStrongElementOnly) {
         return true;
       }
    }
    return false;
   
  })
  .addClass("only-strong");
ul {
  border: 1px solid red;
}

.only-strong {
  color: blue;
  font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="list-style">
  <li><strong>strong</strong> oops fail</li>
</ul>
<ul class="list-style">
  <li>f</li>
</ul>
<ul class="list-style">
  <li>a</li>
  <li>b</li>
</ul>
1 голос
/ 23 октября 2019

Ваш код работает так, как вы ожидаете, просто замените = на == в каждом фильтре return:

$('ul.list-style').filter(function() {
    return $(this).children("li")
      .filter(function() {
        return $(this).contents()
          .filter(function() {
            return this.nodeType == Node.ELEMENT_NODE || (this.nodeType == Node.TEXT_NODE && !!$.trim(this.nodeValue))
          }).length == 1
      })
      .filter(function() {
        return $(this).children("strong").length == 1
      }).length == 1
  })
  .addClass("only-strong");
ul {
  border: 1px solid black;
}

.only-strong {
  color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="list-style">
  <li><strong>strong</strong></li>
</ul>
<ul class="list-style">
  <li>f</li>
</ul>
<ul class="list-style">
  <li>a</li>
  <li>b</li>
</ul>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...