Как обернуть строки в HTML-теги с помощью JavaScript

Мне нужно изменить шрифт всех цифр на странице.

Я думал об использовании insertBefore() и так далее, но потом понял, что его нельзя использовать со строками.

Что у меня есть на данный момент:

  1. Массив со всем текстом на странице.

  2. Массив со всеми цифрами.

  3. Массив, в котором все цифры заменены функцией replace() (неудачная попытка).

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

Как я могу обернуть все элементы массива 'string' тегом span или любым другим тегом?

ПРИМЕЧАНИЕ. Я бы предпочел не использовать innerHTML.

Большое спасибо!

let allText = document.querySelector('body p').textContent;
console.info(allText);

let digits = allText.match(/\d/gi);
console.info(digits);

let rep = allText.replace(/\d/gi, "AA");
console.info(rep);
document.body.textContent = rep;
<!DOCTYPE html>
<html lang = "en">
<head>
    <style>
        body {
            text-align: center;

            font-size: 40px;
        }
    </style>
</head>
<body>
    <p>
        sdfjsdf
        (1): sdfdsdfs --
        (1): sdfdsdfs --
        (2) sdfsdf --
        (3): sdfsdfs --
        sdfdsfsdf --
    </p>

    <script src = "a.js"></script>
</body>
</html>

Где находится массив 'string'?

jabaa 19.08.2024 10:02

Я изменил ваш селектор, чтобы вместо этого получать контент p, чтобы не загрязнять console.infos и allText.

mplungjan 19.08.2024 10:06

Массив строк: «let digits = allText.match(/\d/gi); console.info(digits);» @jabaa

Stuck Overflow 19.08.2024 10:09

У вас есть доступ к HTML? Или это единственный способ сделать то, что вы хотите, с помощью JavaScript?

Davi 19.08.2024 10:17

Этот вопрос похож на: Как обернуть подстроку HTML в теги?. Если вы считаете, что это другое, отредактируйте вопрос, поясните, чем он отличается и/или как ответы на этот вопрос не помогают решить вашу проблему.

jabaa 19.08.2024 10:19

Этот вопрос похож на: Найдите строку текста в элементе и оберните ее тегами span. Если вы считаете, что это другое, отредактируйте вопрос, поясните, чем он отличается и/или как ответы на этот вопрос не помогают решить вашу проблему.

jabaa 19.08.2024 10:21

Да, я бы предпочел не использовать внутренний HTML, спасибо за помощь @Davi

Stuck Overflow 19.08.2024 10:21

«Я бы предпочел не использовать внутренний HTML» Почему? Вы должны упомянуть об этом в вопросе.

jabaa 19.08.2024 10:23

Привет, другой вопрос основан на внутреннем HTML - где мне нужно использовать другие методы @jabaa

Stuck Overflow 19.08.2024 10:24

С textContent этого сделать нельзя. Если у вас есть черный или белый список разрешенных функций, вам следует добавить его в вопрос. Вам также следует объяснить, почему вы не хотите использовать эти функции. Обычно это помогает.

jabaa 19.08.2024 10:26

Потому что я слышал, что не рекомендуется использовать внутренний HTML, поскольку это небезопасно @jabaa

Stuck Overflow 19.08.2024 10:32
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
11
54
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

Пока внутри тегов нет цифр внутри контента

Я изменил на pre, чтобы сохранить список

ПРИМЕЧАНИЕ. Использование InnerHTML МОЖЕТ вызвать некоторые проблемы с XSS. Если содержимое тега P не было очищено, вы рискуете. Итак, вот версия, безопасная для XSS. Я только что прочитал в вашем комментарии, что вам все равно не нужен внутренний HTML.

let allText = document.querySelector('body p').textContent;
console.info(allText);
const outputElement = document.getElementById('output');
outputElement.textContent= ''; // empty the output

allText.split('\n').forEach(line => {
  // Create a container for the line
  const lineElement = document.createElement('div');
  // Split the line into parts by numbers, capturing the numbers to keep them in the result
  const parts = line.split(/(\d+)/);
  console.info(parts)
  parts.forEach(part => { 
    if (/\d+/.test(part)) {
      // wrap a number in a span
      const span = document.createElement('span');
      span.className = 'number';
      span.textContent = part;
      lineElement.appendChild(span);
    } else {
      lineElement.appendChild(document.createTextNode(part));
    }
  });
  outputElement.appendChild(lineElement);
});
.number {
  color: red;
}

/* stop console.info from hiding output */
.as-console-wrapper { height:40px !important;}
<p>
        sdfjsdf
        (1): sdfdsdfs --
        (1): sdfdsdfs --
        (2) sdfsdf --
        (3): sdfsdfs --
        sdfdsfsdf --
    </p>

<pre id = "output"></pre>

Если вас не затруднит, то вот более простой вариант

let allText = document.querySelector('body p').textContent;
console.info(allText);

document.getElementById('output').innerHTML = allText
  .replace(/\d+/g, match => `<span class = "number">${match}</span>`)
.number {
  color: red;
}


.as-console-wrapper { height:40px !important;}
<p>
        sdfjsdf
        (1): sdfdsdfs --
        (1): sdfdsdfs --
        (2) sdfsdf --
        (3): sdfsdfs --
        sdfdsfsdf --
    </p>

<pre id = "output"></pre>

Привет! Это выглядит великолепно! Я не совсем понял, почему люди не используют InternalHTML — но думаю, в нашем случае это не принесет никакого вреда, верно? Спасибо!

Stuck Overflow 19.08.2024 10:29

Смотрите обновление.

mplungjan 19.08.2024 10:43

Вам не нужен lineElement.appendChild(document.createTextNode(part));. lineElement.append(part); достаточно.

Unmitigated 20.08.2024 01:33

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

// Find all the document's text nodes
const treeWalker = document.createTreeWalker(
  document.body,
  NodeFilter.SHOW_TEXT,
);

// Collect the text nodes into an array
const nodes = [];
while (treeWalker.nextNode()) {
  nodes.push(treeWalker.currentNode);
}

// Go through each text node...
for (const node of nodes) {
  const matches = [
    // Find each string of digits, adding them to an array...
    ...node.data.matchAll(/\d+/g)
    //  ...so that we can reverse them (we do this so our indexes
    //    don't become stale after we wrap the first text node)
  ].reverse();
  for (const match of matches) {
    // Create a range to include the sequence of digits
    const range = document.createRange();
    range.setStart(node, match.index);
    range.setEnd(node, match.index + match[0].length);
    // Create our wrapping element
    const newParent = document.createElement('b');
    // Surround the digits with our wrapping element
    range.surroundContents(newParent);
  }
}
<p>This text has 123 some numbers 456 including <i>nested 789</i>.</p>

Интересный подход.

mplungjan 19.08.2024 11:22

Вау, это выглядит действительно продвинуто! Большое спасибо!

Stuck Overflow 19.08.2024 11:22

Мне нужно изменить шрифт всех цифр на странице.

Если ваша главная цель — поменять местами применяемые семейства шрифтов, вы можете рассмотреть подход CSS.

Меняйте шрифты с помощью правил @font-face и unicode-range.

Отказ от ответственности: вы не сможете применять более продвинутые отклонения от стиля, как в уже описанных JS-подходах mplungjan и Бретта Замира.

body {
  font-family: 'open sans', sans-serif;
  font-size: 4vmin;
}


/** 
* display only numbers in lobtser 
* based on a compact subset
**/

@font-face {
  font-family: 'open sans';
  font-style: normal;
  font-weight: 400;
  src: url(https://fonts.gstatic.com/l/font?kit=neILzCirqoswsqX9_oC0PJkDYqbBnEUpnRI&skey=7ed805a363b4659c&v=v30) format('woff2');
  unicode-range: U+30-39;
}

@font-face {
  font-family: 'open sans';
  font-style: italic;
  font-weight: 400;
  src: url(https://fonts.gstatic.com/l/font?kit=neILzCirqoswsqX9_oC0PJkDYqbBnEUpnRI&skey=7ed805a363b4659c&v=v30) format('woff2');
  unicode-range: U+30-39;
}

@font-face {
  font-family: 'open sans';
  font-style: normal;
  font-weight: 700;
  src: url(https://fonts.gstatic.com/l/font?kit=neILzCirqoswsqX9_oC0PJkDYqbBnEUpnRI&skey=7ed805a363b4659c&v=v30) format('woff2');
  unicode-range: U+30-39;
}

@font-face {
  font-family: 'open sans';
  font-style: italic;
  font-weight: 700;
  src: url(https://fonts.gstatic.com/l/font?kit=neILzCirqoswsqX9_oC0PJkDYqbBnEUpnRI&skey=7ed805a363b4659c&v=v30) format('woff2');
  unicode-range: U+30-39;
}
<p>
  sdfjsdf
  <em>(1): sdfdsdfs --</em> (1): sdfdsdfs -- (2) sdfsdf --
  <strong>(3): sdfsdfs --</strong> sdfdsfsdf --
</p>

Как это работает:

Правила @font-face предписывают браузеру сопоставлять указанные font-family, font-style и font-weight определенному файлу шрифта — в данном случае обычному Lobster. Другими словами, мы говорим браузеру применять «Лобстера» для каждого экземпляра обычного, курсивного, полужирного или жирного курсива внутри unicode-range: U+30-39 (0–9).

Основное преимущество: вам не нужно беспокоиться о дорогостоящих манипуляциях с DOM (особенно, если вы применяете его к большим объемам тестов).

Как упоминалось ранее, к этим заменам CSS нельзя применить какие-либо определенные стили (например, цвет).

ПРИМЕЧАНИЕ. Я бы предпочел не использовать внутренний HTML.

На самом деле, вам следует в первую очередь использовать подходы на основе JS в качестве своего рода «препроцессора». Как только вы получите более детальную структуру HTML (например, обертывание подстрок в нужные элементы-обертки), лучше найдите способы постоянного сохранения новой разметки (например, путем обновления записей базы данных или статических HTML-файлов) вместо того, чтобы каждый раз манипулировать содержимым снова и снова. отображается страница/приложение.

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