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

У меня есть два неупорядоченных списка внутри div с известным классом. Мне нужно изменить элементы списка в первом списке, чтобы они охватывали класс «время». Далее я хотел бы изменить элементы второго списка на интервалы с классом «частота». Наконец, я хотел бы удалить теги <ul>, оставив только промежутки в div. Как:

<div id = "training-labels">
<ul>
<li>30 mins</li>
</ul>

<ul>
<li>Annually</li>
<li>First 2 weeks</li>
</ul>
</div>

К этому

<span class = "time">30 mins</span>
<span class = "frequency">Annually</span>
<span class = "frequency">First 2 weeks</span>

Мне удалось изменить содержимое каждого списка на диапазоны:

$('#training-labels ul:nth-of-type(1) li').wrapInner('<span class = "time" />').contents();
$('#training-labels ul:nth-of-type(2) li').wrapInner('<span class = "frequency" />').contents();

Но не удалось удалить теги ul и li, оставив только промежутки.

Это лучший подход или есть лучший способ добиться этого с помощью JQuery?

Я установил здесь Fiddle

$('#training-labels ul:nth-of-type(1) li').wrapInner('<span class = "time" />').contents();

$('#training-labels ul:nth-of-type(2) li').wrapInner('<span class = "frequency" />').contents();
.time {
  color: green;
}

.frequency {
  color: red;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id = "training-labels">
  <ul>
    <li>30 mins</li>
  </ul>

  <ul>
    <li>Annually</li>
    <li>First 2 weeks</li>
  </ul>
</div>

Сделал новую версию без накрутки и энного

mplungjan 18.11.2022 12:50
Как конвертировать HTML в PDF с помощью jsPDF
Как конвертировать HTML в PDF с помощью jsPDF
В этой статье мы рассмотрим, как конвертировать HTML в PDF с помощью jsPDF. Здесь мы узнаем, как конвертировать HTML в PDF с помощью javascript.
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Учебник по Javascript
Учебник по Javascript
JavaScript - это язык программирования, который обычно используется для добавления интерактивности и других динамических функций на веб-сайты. Он...
Анимация SVG-узоров без единой строки CSS
Анимация SVG-узоров без единой строки CSS
Недавно я работал над веб-проектом, который позволил мне поэкспериментировать с шаблонами SVG. С SVG очень приятно работать, как только вы получите...
5 распространенных ошибок, которых следует избегать при начале работы с HTML
5 распространенных ошибок, которых следует избегать при начале работы с HTML
Приветствую вас, изучающие HTML! Я составил список распространенных ошибок, которые часто допускают студенты, начинающие изучать HTML. Пожалуйста,...
Неделя 1 - Карточки с временной шкалой
Неделя 1 - Карточки с временной шкалой
Поскольку это была первая неделя, я решил начать с простого. Предполагалось, что у меня будет временная шкала с несколькими карточками, которые можно...
1
1
52
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Вы можете сделать следующее:

$('#training-labels ul:nth-of-type(1) li').wrap('<span class = "time"/>').contents().unwrap();

$('#training-labels ul:nth-of-type(2) li').wrap('<span class = "frequency"/>').contents().unwrap();

$('#training-labels ul:nth-of-type(1) span').unwrap();
$('#training-labels ul:nth-of-type(1) span').unwrap();

  
.time {
  color: green;
}

.frequency {
  color: red;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id = "training-labels">
  <ul>
    <li>30 mins</li>
  </ul>

  <ul>
    <li>Annually</li>
    <li>First 2 weeks</li>
  </ul>
</div>

Метод JQuery wrap():

Функция .wrap() может принимать любую строку или объект, которые можно передать фабричной функции $() для указания структуры DOM.

Метод JQuery unwrap():

Удалите родителей набора совпадающих элементов из DOM, оставив совпавшие элементы на их месте.

Примечание. Поскольку к родительскому элементу div (с идентификатором training-labels) не прикреплен класс, оба интервала находятся в одной строке.

Спасибо за объяснение, это сработало! Хотя я заменил последние две строки на $('#training-labels ul span').unwrap(); чтобы развернуть все промежутки одновременно.

ScreamQueen 18.11.2022 12:26

Если мы можем быть уверены, что у всех ul1 есть времена, а у всех ul2 есть частоты

const $div = $('#training-labels');
const $uls = $('ul', $div); // save
$div.empty(); // clear
$uls.each(function(i, ul) {
  $("li", ul).each(function(j, li) {
    $(`<span class = "${i===0 ? "time" : "frequency" }">${li.textContent}</span><br/>`)
      .appendTo($div)
  });
});
.time {
  color: green;
}

.frequency {
  color: red;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id = "training-labels">
  <ul>
    <li>30 mins</li>
  </ul>
  <ul>
    <li>Annually</li>
    <li>First 2 weeks</li>
  </ul>
</div>

В противном случае

const $div = $('#training-labels')
$('ul:nth-of-type(1) li', $div).wrapInner('<span class = "time" />').contents();
$('ul:nth-of-type(2) li', $div).wrapInner('<span class = "frequency" />').contents();
$div.html(function() { 
  return $div.find("span")
    .map(function() { return this.outerHTML })
    .get()
    .join("<br/>"); // or space or something else
});
.time {
  color: green;
}

.frequency {
  color: red;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id = "training-labels">
  <ul>
    <li>30 mins</li>
  </ul>
  <ul>
    <li>Annually</li>
    <li>First 2 weeks</li>
  </ul>
</div>

Мой подход

let $div = $('#training-labels');
let $time = $('ul:nth-of-type(1) li', $div).clone().wrapInner('<span class = "time" />').contents();
let $freq = $('ul:nth-of-type(2) li', $div).clone().wrapInner('<span class = "frequency" />').contents();
$div.replaceWith($().add($time).add($freq));

Это не отличается от решения unwrap, за исключением того, что оно не так сильно привязано к структуре тега. Часть clone не является строго обязательной, но это означает, что на самом деле существует только одно обновление DOM, которое происходит после создания полной замены.

Хотя вы уже приняли ответ, я хотел бы найти время, чтобы показать не-JavaScript (или jQuery) подход, основанный только на CSS, который может работать для вас, в зависимости от желаемого конечного результата:

/* a simple reset to remove default font-sizes, box-sizing, margins and padding: */
*, ::before, ::after {
  box-sizing: border-box;
  font-family: system-ui;
  font-size: 16px;
  margin: 0;
  padding: 0;
}

/* removing default list-markers from the <li> elements: */
ul {
  list-style-type: none;
}

/* wrapping the outer <div> elements which wrap your <ul>
   elements in a <main> element in order to style and
   align the content; this is unnecessary for the demo
   functionality: */
main {
  /* taking advantage of grid display to position items on
     the vertical (block) axis: */
  display: grid;
  /* separating tracks with a 'gutter': */
  gap: 1em;
  /* defining the inline-size - the size of the element
     along the inline-axis (horizontal in most latin-
     derived languages, such as French, English...): */
  inline-size: clamp(15rem, 70vw, 1100px);
  /* a 1em margin before the start of the element on its
     block axis (perpendicular to the inline axis,
     vertical in most Latin-derived languages): */
  margin-block-start: 1em;
  /* using margins to centre the element: */
  margin-inline: auto;
}

/* default styles for the .content elements (the class-name
   given to the <div> elements which wrap the <ul> elements:*/
.content {
  border: 2px solid var(--color, currentColor);
  padding: 0.5em;
}

/* styling the <li> elements as inline-block; which allows them
   to flow inline but take a specified size (inline or block),
   and margins: */
#inlineBlock li {
  display: inline-block;
}

/* using flex layout on the <ul> elements, which positions the
   <li> children along the inline-axis (by default) while allowing
   them to be sized according to their content or declaration: */
#flex ul {
  display: flex;
}

/* this was posted purely for the sake of completeness, and I don't
   recommend it since the track sizing looks more tabular than
   is possibly required: */
#grid {
  display: grid;
  /* this defines two columns with each column sized to fit the
     content within: */
  grid-template-columns: repeat(2, fit-content);
}

#grid ul {
  /* we use this to effectively pretend the <ul> elements don't
     exist, to allow the <li> elements to be placed into the
     grid rather than the <ul> elements: */
  display: contents;
}

/* because each row/column track of a grid has an equal number of
   divisions/"cells", and because we're pretending (display: contents)
   that the <ul> elements don't exist, this is to ensure that
   the <li> contents of the second <ul> don't fill the first row track;
   this can be adjusted if you'd prefer that to happen, but I didn't
   expect that it's required: */
#grid li:only-child {
  grid-column: span 2;
}

/* going back to the land before time, we use a simple floats to
   allow the <li> elements to run inline: */
#float li {
  float: left;
}

/* to ensure the first <li> always starts on a new line: */
#float li:first-child {
  clear: left;
}

/* selecting all <li> elements that are not the :first-child,
   contained within a <div> that does not have an id of "grid": */
.content:is(:not(#grid)) li:not(:first-child)::before {
  /* placing a comma before those elelements: */
  content: ", ";
}

/* selecting the :last-child <li> descendant of .content elements
   (which do not have the id of "grid"), and styling their ::after
   pseudo-element: */
.content:is(:not(#grid)) li:last-child::after {
  /* adding a full-stop/period: */
  content: '.';
}

/* styling the ::after pseudo-element of an <li> which is the :only-child
   of its parent, and within a .content element without the id of "grid": */
.content:is(:not(#grid)) li:only-child::after {
  /* adding a colon after the text of the element: */
  content: ': ';
}
<main>
  <div id = "inlineBlock" class = "content" style = "--color: hsl(120deg 80% 70% / 1)">
    <ul>
      <li>30 mins</li>
    </ul>

    <ul>
      <li>Annually</li>
      <li>First 2 weeks</li>
    </ul>
  </div>
  
  <div id = "flex" class = "content" style = "--color: hsl(160deg 80% 70% / 1)">
    <ul>
      <li>30 mins</li>
    </ul>

    <ul>
      <li>Annually</li>
      <li>First 2 weeks</li>
    </ul>
  </div>
  
  <div id = "grid" class = "content" style = "--color: hsl(200deg 80% 70% / 1)">
    <ul>
      <li>30 mins</li>
    </ul>

    <ul>
      <li>Annually</li>
      <li>First 2 weeks</li>
    </ul>
  </div>
  
  <div id = "float" class = "content" style = "--color: hsl(240deg 80% 70% / 1)">
    <ul>
      <li>30 mins</li>
    </ul>

    <ul>
      <li>Annually</li>
      <li>First 2 weeks</li>
    </ul>
  </div>
</main>

Демонстрация JS Fiddle.

Использованная литература:

CSS:

Другие вопросы по теме