jQuery получает разные значения из одного и того же элемента и использует их как разные классы

#jquery #arrays

Вопрос:

Я изо всех сил пытаюсь найти способ получить текст дочерних элементов и использовать их в качестве отдельных классов для родительского элемента. У меня вроде как есть логика, но я не могу найти способ разделить каждый класс.

Чтобы усложнить задачу, я хочу удалить специальные символы, заменить пробелы и поместить все в нижний регистр. Я думаю, что я уже получил эту часть (надеюсь).

В любом случае… У меня есть этот html-код:

 <div class="parent">
   <div class="child">Child #1</div>
   <div class="child">Child #2</div>
   <div class="child">Child #3</div>
   <div class="child">Child #4</div>
</div>
<div class="parent">
   <div class="child">Child #A</div>
   <div class="child">Child #b</div>
   <div class="child">Child #9</div>
   <div class="child">Child #K</div>
</div>
 

Что я хочу видеть, так это следующее:

 <div class="parent new_child_1 new_child_2 new_child_3 new_child_4">
   <div>Child #1</div>
   <div>Child #2</div>
   <div>Child #3</div>
   <div>Child #4</div>
</div>
<div class="parent new_child_a new_child_b new_child_3 new_child_1">
   <div>Child #A</div>
   <div>Child #b</div>
   <div>Child #3</div>
   <div>Child #1</div>
</div>
 

Так что я добрался до этого до сих пор:

 $(".parent").each(function(){
        var child_text = $(this).find(".child").text();
        var new_class = child_text.replace(/[^a-z0-9s]/gi, '').replace(/[_s]/g, '_').toLowerCase()
        $(this).addClass("new_"   new_class);
});
 

Но я получаю одну строку всех текстов (т. Е. «new_child_1child_2child_3child_4»).

Спасибо всем, кто поможет.

Ответ №1:

Вы могли бы создать массив из детей и использовать Array.reduce , как это:

 $(".parent").each(function() {
  var children = $(this).find('.child');
  var new_class = Array.from(children).reduce((carry, child) => {
    var text = child.innerText.replace(/[^a-z0-9s]/gi, '').replace(/[_s]/g, '_').toLowerCase();

    carry  = `new_${text} `;

    return carry;
  }, '');
  console.log(new_class);
  $(this).addClass(new_class);
}); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent">
  <div class="child">Child #1</div>
  <div class="child">Child #2</div>
  <div class="child">Child #3</div>
  <div class="child">Child #4</div>
</div>
<div class="parent">
  <div class="child">Child #A</div>
  <div class="child">Child #b</div>
  <div class="child">Child #9</div>
  <div class="child">Child #K</div>
</div> 

Комментарии:

1. Спасибо! Вот и все! Спасибо всем, кто мне помог 🙂

Ответ №2:

вы выполняете итерацию только для родителей, вам нужно выполнить итерацию непосредственно для детей. Я еще не пробовал этого, но я считаю, что это должно быть близко.

 $(".parent").children().each(function(){
        var child_text = $(this).text();
        var new_class = child_text.replace(/[^a-z0-9s]/gi, '').replace(/[_s]/g, '_').toLowerCase()
        $(this).addClass("new_"   new_class);
});
 

Изменить: Если вам просто нужно добавить пробел, вы можете сделать это в функции:

 $(".parent").each(function(){
        var child_text = $(this).find(".child").text();
        var new_class = child_text.replace(/[^a-z0-9s]/gi, '').replace(/[_s]/g, '_').toLowerCase()
        // check if newclass has data, if it does, add a leading space
        if (new_class.length > 0) { $(this).addClass(" new_"   new_class); );
});
 

Комментарии:

1. Спасибо вам за ваш ответ. К сожалению, это не работает, так как он добавляет один класс со всеми текстами элементов вместо добавления одного класса для текста каждого дочернего элемента

2. Вы хотите, чтобы у родителя были классы всех «new_child», применимые к нему, а не к детям?

3. да, я хотел бы, чтобы у родительского элемента были разные классы, названные как текст каждого дочернего элемента, который он содержит. Все они с префиксом «new_». Единственное, что я не могу заставить себя работать, — это разделить все тексты на разные классы. Мне удается создать только огромный класс, название которого является соединением всех текстов дочерних элементов.

4. Я добавил правку, которая может сработать, чтобы правильно разделить имена.

5. Еще раз спасибо вам за ответ и за помощь. К сожалению, он по-прежнему создает только один класс «new_child_1child_2child_3child_4» вместо 4 разных классов «new_child_1 new_child_2 new_child_3 new_child_4».

Ответ №3:

Если нужный вам символ всегда стоит после #, вы можете использовать функцию разделения, например

отредактированный

 $(".parent").each(function() {
  var childs = [];
  $(this).find(".child").each(function(key) {
    childs[key]='new_child_' $(this).text().replace(/[^a-z0-9s]/gi, '').replace(/[_s]/g, '_').toLowerCase();
    $(this).removeClass('child');
  });

  console.log(childs.join(' '));
  $(this).addClass(childs.join(' '));
}); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="parent">
  <div class="child">Child #1</div>
  <div class="child">Child #2</div>
  <div class="child">aBc*d#</div>
  <div class="child">Child #4</div>
</div>
<div class="parent">
  <div class="child">Child #A</div>
  <div class="child">Child #b</div>
  <div class="child">Child #9</div>
  <div class="child">Child #K</div>
</div> 

Комментарии:

1. Спасибо вам за ваш ответ. Нет, текст будет случайным и не всегда будет содержать #.

2. Отредактированный код, что-то в этом роде?

3. Да, это тоже работает! Спасибо!